After configuring SSO, I encountered the following error when trying to log in using SSO. Has anyone experienced a similar issue?
2026-08-26T08:08:46.663Z | error | Failed to exchange authorization code for tokens server responded with a challenge in the WWW-Authenticate HTTP Header {“code”:“OAUTH_WWW_AUTHENTICATE_CHALLENGE”,“file”:“oidc.service.ee.js”,“function”:“logTokenExchangeError”}
ResponseError: Invalid authorization code
at OidcService.loginUser (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.service.ee.ts:284:10)
at processTicksAndRejections (node:internal/process/task_queues:104:5)
at OidcController.callbackHandler (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.controller.ee.ts:144:29)
at handler (/usr/local/lib/node_modules/n8n/src/controller.registry.ts:115:12)
at /usr/local/lib/node_modules/n8n/src/controller.registry.ts:124:7
2026-08-26T08:08:48.586Z | debug | Heartbeat updated {“scopes”:[“instance-registry”],“file”:“instance-registry.service.js”}
2026-08-26T08:08:58.384Z | error | Failed to exchange authorization code for tokens server responded with a challenge in the WWW-Authenticate HTTP Header {“code”:“OAUTH_WWW_AUTHENTICATE_CHALLENGE”,“file”:“oidc.service.ee.js”,“function”:“logTokenExchangeError”}
ResponseError: Invalid authorization code
at OidcService.loginUser (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.service.ee.ts:284:10)
at processTicksAndRejections (node:internal/process/task_queues:104:5)
at OidcController.callbackHandler (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.controller.ee.ts:144:29)
at handler (/usr/local/lib/node_modules/n8n/src/controller.registry.ts:115:12)
at /usr/local/lib/node_modules/n8n/src/controller.registry.ts:124:7
2026-08-26T08:09:18.587Z | debug | Heartbeat updated {“scopes”:[“instance-registry”],“file”:“instance-registry.service.js”}
2026-08-26T08:09:23.377Z | error | Failed to exchange authorization code for tokens server responded with a challenge in the WWW-Authenticate HTTP Header {“code”:“OAUTH_WWW_AUTHENTICATE_CHALLENGE”,“file”:“oidc.service.ee.js”,“function”:“logTokenExchangeError”}
ResponseError: Invalid authorization code
at OidcService.loginUser (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.service.ee.ts:284:10)
at processTicksAndRejections (node:internal/process/task_queues:104:5)
at OidcController.callbackHandler (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.controller.ee.ts:144:29)
at handler (/usr/local/lib/node_modules/n8n/src/controller.registry.ts:115:12)
at /usr/local/lib/node_modules/n8n/src/controller.registry.ts:124:7
2026-08-26T08:09:44.879Z | debug | Querying database for waiting executions {“scopes”:[“waiting-executions”],“file”:“wait-tracker.js”,“function”:“getWaitingExecutions”}
Hi @yushaojian Welcome!
A WWW-Authenticate challenge on the token endpoint is the IdP rejecting n8n’s client authentication, not the code. n8n throws “Invalid authorization code” for every failed token exchange, so that string is not what Oracle sent back.
Test the credentials on their own against the same endpoint:
curl -i -u '<client-id>:<client-secret>' -d 'grant_type=client_credentials' <token_endpoint from your discovery document>
A 401 there is Oracle refusing the ID and secret pair, any other status means client authentication passed. Regenerate the secret on the confidential application, confirm it is Activated with Authorization Code in Allowed Grant Types, then re-paste both values under Settings > SSO.
That 400 is the probe succeeding, not failing. unauthorized_client is a post-authentication error, Oracle checked the id and secret pair, accepted it, and only then refused the grant type the probe was borrowing as a credential check. Your credentials are correct, and n8n never uses client_credentials in its login flow, so there is nothing to adjust on the grant side.
The difference between your curl and n8n is where the secret travels. Your curl sent it in the Authorization header. n8n passes no client auth method to its OIDC library, and openid-client’s discovery() defaults to client_secret_post, the secret as a form body parameter. Oracle’s token endpoint documents client authentication through the Basic Authorization header, with a body client_id reserved for client assertions, so it treats n8n’s body-authenticated exchange as unauthenticated and answers with the WWW-Authenticate challenge from your log.
Confirm it on your domain by moving the secret into the body:
The GitHub bot(n8n assistant) has rejected my request. May I ask if there are any other solutions? For example, adjusting the configuration of Oracle IAM!
OIDC SSO is an Enterprise feature, and self-hosted Enterprise carries email support with an SLA for technical issues, so this belongs with help@n8n.io rather than the public issue tracker. Send them both curl results and the log lines from your first post.
Before that, the discovery document n8n already reads will tell you whether Oracle has anything to change:
curl -s <your discovery endpoint>
Look at token_endpoint_auth_methods_supported in the response. If client_secret_post is absent from that list, the domain does not accept it at all and no application setting will add it, which makes that one line the cleanest evidence for the ticket.
2026-08-31T02:21:56.485Z | debug | Heartbeat updated {"scopes":["instance-registry"],"file":"instance-registry.service.js"}
2026-08-31T02:22:12.013Z | error | Failed to exchange authorization code for tokens server responded with a challenge in the WWW-Authenticate HTTP Header {"code":"OAUTH_WWW_AUTHENTICATE_CHALLENGE","file":"oidc.service.ee.js","function":"logTokenExchangeError"}
ResponseError: Invalid authorization code
at OidcService.loginUser (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.service.ee.ts:284:10)
at processTicksAndRejections (node:internal/process/task_queues:104:5)
at OidcController.callbackHandler (/usr/local/lib/node_modules/n8n/src/modules/sso-oidc/oidc.controller.ee.ts:144:29)
at handler (/usr/local/lib/node_modules/n8n/src/controller.registry.ts:115:12)
at /usr/local/lib/node_modules/n8n/src/controller.registry.ts:124:7
2026-08-31T02:22:26.485Z | debug | Heartbeat updated {"scopes":["instance-registry"],"file":"instance-registry.service.js"}
There is no log level that will surface it, and you are already on debug, the Heartbeat lines in your paste are debug output. n8n’s token exchange handler logs oauthError, oauthErrorDescription, code and message, and skips the error’s cause by design. A WWW-Authenticate challenge carries no top level error or error_description, the reason sits only in cause, so both fields resolve to undefined and your line prints code on its own.
Oracle kept the reason. In the identity domain, open Reports > Audit Log, set Event description to “Application access failed” and filter to your confidential application. That entry holds the rejection reason n8n is discarding.