diff --git a/lib/utils/user-info-extraction-utils.js b/lib/utils/user-info-extraction-utils.js
--- a/lib/utils/user-info-extraction-utils.js
+++ b/lib/utils/user-info-extraction-utils.js
@@ -1,32 +1,69 @@
 // @flow
 
 import _memoize from 'lodash/memoize.js';
-import t, { type TType } from 'tcomb';
+import t, { type TType, type TInterface } from 'tcomb';
 
 import type { CallSingleKeyserverEndpointResponse } from '../keyserver-conn/call-single-keyserver-endpoint.js';
 import { mixedRawThreadInfoValidator } from '../permissions/minimally-encoded-raw-thread-info-validators.js';
 import type { Endpoint } from '../types/endpoints.js';
+import type { MixedRawThreadInfos } from '../types/thread-types.js';
 import { userInfoValidator } from '../types/user-types.js';
+import type { UserInfo } from '../types/user-types.js';
 import { endpointValidators } from '../types/validators/endpoint-validators.js';
 import { extractUserIDsFromPayload } from '../utils/conversion-utils.js';
 import { tID, tShape } from '../utils/validation-utils.js';
 
-function extendResponderValidatorBase(inputValidator: TType<*>): TType<*> {
-  return tShape({
-    ...inputValidator.meta.props,
-    cookieChange: t.maybe(
-      tShape({
-        threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
-        userInfos: t.list(userInfoValidator),
-        cookieInvalidated: t.maybe(t.Boolean),
-        sessionID: t.maybe(t.String),
-        cookie: t.maybe(t.String),
-      }),
-    ),
-    error: t.maybe(t.String),
-    payload: t.maybe(t.Object),
-    success: t.maybe(t.Boolean),
-  });
+type AdditionalCookieChange = {
+  +threadInfos: MixedRawThreadInfos,
+  +userInfos: $ReadOnlyArray<UserInfo>,
+  +cookieInvalidated?: boolean,
+  sessionID?: string,
+  cookie?: string,
+};
+
+type AdditionalResponseFields = {
+  +cookieChange: AdditionalCookieChange,
+  +error?: string,
+  +payload?: Object,
+  +success: boolean,
+};
+
+const additionalResponseFieldsValidator = tShape<AdditionalResponseFields>({
+  cookieChange: t.maybe(
+    tShape<AdditionalCookieChange>({
+      threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
+      userInfos: t.list(userInfoValidator),
+      cookieInvalidated: t.maybe(t.Boolean),
+      sessionID: t.maybe(t.String),
+      cookie: t.maybe(t.String),
+    }),
+  ),
+  error: t.maybe(t.String),
+  payload: t.maybe(t.Object),
+  success: t.maybe(t.Boolean),
+});
+
+function extendResponderValidatorBase<T>(inputValidator: TType<T>): TType<T> {
+  if (inputValidator.meta.kind === 'union') {
+    const newTypes = [];
+    for (const innerValidator of inputValidator.meta.types) {
+      const newInnerValidator = extendResponderValidatorBase(innerValidator);
+      newTypes.push(newInnerValidator);
+    }
+    return t.union(newTypes);
+  } else if (inputValidator.meta.kind === 'interface') {
+    const recastValidator: TInterface<Object> = (inputValidator: any);
+
+    return (tShape({
+      ...recastValidator.meta.props,
+      ...additionalResponseFieldsValidator.meta.props,
+    }): any);
+  } else if (inputValidator.meta.kind === 'maybe') {
+    const typeObj = extendResponderValidatorBase(inputValidator.meta.type);
+    return (t.maybe(typeObj): any);
+  }
+
+  return inputValidator;
 }
 
 const extendResponderValidator = _memoize(extendResponderValidatorBase);