mongodb/node-mongodb-native · error · MongoOIDCError
OIDC callback timed out after
Error message
OIDC callback timed out after ${HUMAN_TIMEOUT_MS}ms. What it means
Thrown by the OIDC human (interactive) callback workflow (human_callback_workflow.ts:134) when the user-supplied callback function does not settle within 5 minutes (HUMAN_TIMEOUT_MS = 300000, defined in callback_workflow.ts:18). The workflow races the callback against a Timeout and, on timeout, aborts the callback via AbortController and rethrows as MongoOIDCError. This deadline exists because the human workflow performs interactive browser login.
Solutions
- Make your OIDC callback honor params.timeoutContext: abort in-flight HTTP and close popups when the signal aborts
- Ensure the interactive login completes within 5 minutes, or catch the error and re-trigger connection
- For non-interactive workloads, switch to a machine workflow (ENVIRONMENT=gcp/azure/k8s) or a cached token callback instead of the human flow
Example fix
// before
const callback = async (params) => {
const token = await fetchTokenIgnoreSignal(); // never aborts
return { accessToken: token };
};
// after
const callback = async (params) => {
const res = await fetch(tokenUrl, { signal: params.timeoutContext });
const json = await res.json();
return { accessToken: json.access_token };
}; Defensive patterns
Strategy: retry
Try / catch
try {
await client.connect();
} catch (err) {
if (err instanceof MongoOIDCError && /callback timed out/.test(err.message)) {
// re-prompt the user / re-attempt interactive login; the cache is cleared so a retry re-runs the flow
await retryInteractiveLogin();
} else throw err;
} Prevention
- Always honor params.timeoutContext (AbortSignal) inside your OIDC callback and abort in-flight HTTP when it fires
- Keep the interactive login UI responsive and auto-close on success
- For non-interactive workloads, prefer the machine workflow over the human callback to avoid the 5-minute deadline
When it happens
Trigger: Registering an authMechanismProperties callback (human flow) for MONGODB-OIDC whose returned promise neither resolves nor rejects within 300000ms. Typical when the callback opens a browser/server for the user to log in and the user never completes it, or the callback awaits an event that never fires and ignores the params.timeoutContext AbortSignal.
Common situations: User walks away during interactive login. The callback's local HTTP server/popup hangs on a network error. The callback does not honor params.timeoutContext (the AbortSignal) and blocks forever. A token endpoint in the callback is unreachable and never times out on its own.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- OIDC callback timed out after
- User provided OIDC callbacks must return a valid object…
- Auth mechanism property ALLOWED_HOSTS must be an array of…
- AuthContext must provide credentials.
- Azure endpoint did not return a value with only…
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/c43eea4ecf8d22ba.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/auth/mongodb_oidc/human_callback_workflow.ts:134
const controller = new AbortController();
const params: OIDCCallbackParams = {
timeoutContext: controller.signal,
version: OIDC_VERSION,
idpInfo: idpInfo
};
if (credentials.username) {
params.username = credentials.username;
}
if (refreshToken) {
params.refreshToken = refreshToken;
}
const timeout = Timeout.expires(HUMAN_TIMEOUT_MS);
try {
return await Promise.race([this.executeAndValidateCallback(params), timeout]);
} catch (error) {
if (TimeoutError.is(error)) {
controller.abort();
throw new MongoOIDCError(`OIDC callback timed out after ${HUMAN_TIMEOUT_MS}ms.`);
}
throw error;
} finally {
timeout.clear();
}
}
}
View on GitHub (pinned to dce7939f86)