{"record":{"id":"a6f0d383701178d2","repo":"karatelabs/karate","slug":"authorization-flow-failed-e-getmessage","errorCode":null,"errorMessage":"Authorization flow failed: \" + e.getMessage()","messagePattern":"Authorization flow failed: \" \\+ e\\.getMessage\\(\\)","errorType":"exception","errorClass":"OAuth2Exception","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java","lineNumber":120,"sourceCode":"\n            logger.debug(\"Authorization code received\");\n\n            // 5. Exchange code for token\n            OAuth2Token token = exchangeCodeForToken(\n                builder.forkNewBuilder(),\n                code,\n                pkce.getVerifier(),\n                redirectUri\n            );\n\n            // 6. Store token\n            tokenManager.storeToken(token);\n\n            return token;\n\n        } catch (Exception e) {\n            logger.error(\"Authorization flow failed: {}\", e.getMessage());\n            throw new OAuth2Exception(\"Authorization flow failed: \" + e.getMessage(), e);\n        } finally {\n            if (callbackServer != null) {\n                callbackServer.stop();\n            }\n        }\n    }\n\n    /**\n     * Build authorization URL with all required parameters\n     */\n    private String buildAuthorizationUrl(PkceGenerator pkce, String redirectUri) {\n        String authzEndpoint = (String) config.get(\"authorizationUrl\");\n        if (authzEndpoint == null) {\n            throw new OAuth2Exception(\"Missing 'authorizationUrl' in OAuth config\");\n        }\n\n        String clientId = (String) config.get(\"client_id\");\n        if (clientId == null) {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java#L102-L138","documentation":"performAuthorizationFlow() runs the full OAuth2 authorization-code + PKCE flow: open browser, wait for the callback, exchange the code, store the token. Any exception inside the flow (browser failed to open, user cancelled, callback timeout, token exchange HTTP error) is caught, logged, and rethrown as an OAuth2Exception wrapping the original message; the local callback server is stopped in finally.","triggerScenarios":"Any failure inside apply() -> performAuthorizationFlow(): the token endpoint rejects the code exchange, the callback server never receives a redirect, PKCE verification fails, or the authorization page errors.","commonSituations":"Wrong token endpoint URL or client secret, redirect_uri mismatch with the provider's registered redirect, provider downtime, or the user taking longer than the callback timeout to authenticate.","solutions":["Read the wrapped cause (getMessage() plus getCause()) to identify the failing stage","Verify authorizationUrl, token url, client_id and redirect_uri against the provider's app registration","Confirm the provider is reachable and the callback port is free","Increase the callback wait timeout and retry the flow"],"exampleFix":"// before\nconfig.put(\"redirect_uri\", \"http://localhost:8080/callback\"); // not registered\n// after\nconfig.put(\"redirect_uri\", \"http://localhost:5177/callback\"); // matches registered redirect","handlingStrategy":"try-catch","validationCode":"// pre-flight config check before starting the flow\nif (config.get(\"authorizationUrl\") == null || config.get(\"client_id\") == null\n    || config.get(\"url\") == null || config.get(\"redirect_uri\") == null) {\n    throw new IllegalArgumentException(\"Incomplete OAuth config\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Token t = handler.apply(request);\n} catch (OAuth2Exception e) {\n    if (e.getMessage().startsWith(\"Authorization flow failed\")) {\n        logger.warn(\"OAuth flow failed: {} cause={}\", e.getMessage(), e.getCause());\n        // inspect cause: callback timeout vs token exchange HTTP error\n    } else { throw e; }\n}","preventionTips":["Register the exact redirect_uri with the provider beforehand","Pre-validate all OAuth config keys before invoking the flow","Ensure the local callback port is free and not firewalled","Set the callback timeout generously for interactive logins"],"tags":["oauth2","authentication","authorization-code-flow","pkce"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}