{"record":{"id":"457971dec6d90870","repo":"apache/dolphinscheduler","slug":"oidc-token-exchange-failed","errorCode":"OIDC_TOKEN_EXCHANGE_FAILED","errorMessage":"OIDC_TOKEN_EXCHANGE_FAILED","messagePattern":"OIDC_TOKEN_EXCHANGE_FAILED","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/oidc/OidcAuthenticator.java","lineNumber":254,"sourceCode":"\n            ClientAuthentication clientAuth;\n            if (\"client_secret_post\".equalsIgnoreCase(providerConfig.getClientAuthenticationMethod())) {\n                clientAuth = new ClientSecretPost(clientID, clientSecret);\n            } else {\n                clientAuth = new ClientSecretBasic(clientID, clientSecret);\n            }\n\n            TokenRequest tokenRequest = new TokenRequest(\n                    providerMetadata.getTokenEndpointURI(),\n                    clientAuth,\n                    codeGrant);\n\n            TokenResponse tokenResponse;\n            try {\n                tokenResponse = OIDCTokenResponseParser.parse(tokenRequest.toHTTPRequest().send());\n            } catch (Exception e) {\n                log.error(\"Failed to send token request\", e);\n                throw new ServiceException(Status.OIDC_TOKEN_EXCHANGE_FAILED);\n            }\n\n            if (!tokenResponse.indicatesSuccess()) {\n                log.error(\"Token request failed: {}\", tokenResponse.toErrorResponse().getErrorObject());\n                throw new ServiceException(Status.OIDC_TOKEN_EXCHANGE_FAILED);\n            }\n\n            return ((OIDCTokenResponse) tokenResponse).getOIDCTokens();\n        } catch (java.net.URISyntaxException e) {\n            log.error(\"Invalid redirect URI configured for OIDC provider: {}\", providerId, e);\n            throw new ServiceException(\"Failed to construct OIDC redirect URI\", e);\n        }\n    }\n\n    /**\n     * Validate ID token and extract claims\n     */\n    private IDTokenClaimsSet validateIdToken(OIDCProviderMetadata providerMetadata,","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/oidc/OidcAuthenticator.java#L236-L272","documentation":"exchangeCodeForTokens sends the OIDC authorization-code token request via Nimbus OAuth2 SDK. If the HTTP request itself throws (network error, malformed response, parse failure), OIDCTokenResponseParser.parse or send() raises and the code wraps it in ServiceException(Status.OIDC_TOKEN_EXCHANGE_FAILED). Called from the tokens() endpoint during OIDC login callback.","triggerScenarios":"User completing OIDC login: the callback's code is exchanged at the token endpoint but the HTTP send fails (connection refused/TLS error/timeout) or the provider returns an unparseable body, so parse() throws.","commonSituations":"OIDC provider unreachable from the api-server (firewall, wrong issuer/token-endpoint URL); token endpoint misconfigured; provider down; TLS certificate not trusted by the JVM; provider returning HTML error page instead of JSON.","solutions":["Check api-server logs for the underlying 'Failed to send token request' exception to find the root cause (connectivity/TLS/parse)","Verify the OIDC provider token endpoint URL and network reachability from the api-server (curl the token endpoint)","Import the provider's TLS certificate into the JVM truststore if it's a certificate error","Confirm the OIDC provider is up and the configured issuer/discovery URL is correct"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// verify token endpoint reachability before login flow\nHttpURLConnection c = (HttpURLConnection) new URL(tokenEndpoint).openConnection();\nc.setConnectTimeout(5000);\nif (c.getResponseCode() < 200 || c.getResponseCode() >= 500) {\n    throw new IllegalStateException(\"OIDC provider unreachable: \" + tokenEndpoint);\n}","typeGuard":null,"tryCatchPattern":"try {\n    loginViaOidc(authorizationCode);\n} catch (ServiceException e) {\n    if (Status.OIDC_TOKEN_EXCHANGE_FAILED.equals(e.getCode())) {\n        log.error(\"OIDC token exchange failed; check provider reachability and TLS trust\");\n    }\n}","preventionTips":["Monitor OIDC provider availability from the api-server network","Pre-import provider TLS certificates into the JVM truststore","Verify issuer/token-endpoint configuration after provider upgrades"],"tags":["oidc","network","authentication"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}