{"record":{"id":"b54ec638aa077ea6","repo":"karatelabs/karate","slug":"could-not-start-callback-server-on-any-configured-port-ports","errorCode":null,"errorMessage":"Could not start callback server on any configured port: [ports]. Please ensure at least one port is available, or configure different ports using 'callbackPort' or 'callbackPorts'. These ports must be registered as redirect URIs with your OAuth provider.","messagePattern":"Could not start callback server on any configured port: \\[ports\\]\\. Please ensure at least one port is available, or configure different ports using 'callbackPort' or 'callbackPorts'\\. These ports must be registered as redirect URIs with your OAuth provider\\.","errorType":"exception","errorClass":"OAuth2Exception","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java","lineNumber":243,"sourceCode":"     * Start callback server on configured or default ports\n     */\n    private String startCallbackServer(LocalCallbackServer server) {\n        int[] ports = getConfiguredPorts();\n\n        Exception lastException = null;\n        for (int port : ports) {\n            try {\n                String redirectUri = server.start(port);\n                logger.debug(\"Callback server started on port {}\", port);\n                return redirectUri;\n            } catch (Exception e) {\n                logger.warn(\"Port {} in use, trying next port\", port);\n                lastException = e;\n            }\n        }\n\n        // If all configured ports fail, provide helpful error message\n        throw new OAuth2Exception(\n            \"Could not start callback server on any configured port: \" + java.util.Arrays.toString(ports) + \". \" +\n            \"Please ensure at least one port is available, or configure different ports using 'callbackPort' or 'callbackPorts'. \" +\n            \"These ports must be registered as redirect URIs with your OAuth provider.\",\n            lastException\n        );\n    }\n\n    /**\n     * Get configured callback ports or use defaults\n     */\n    private int[] getConfiguredPorts() {\n        // Check for single port configuration\n        Object callbackPort = config.get(\"callbackPort\");\n        if (callbackPort != null) {\n            return new int[] { parsePort(callbackPort) };\n        }\n\n        // Check for multiple ports configuration","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java#L225-L261","documentation":"OAuth2Exception thrown by AuthorizationCodeAuthHandler.startCallbackServer when none of the configured callback ports (callbackPort / callbackPorts) can be bound. Karate runs a temporary local HTTP server to receive the OAuth redirect; without a bound port the authorization-code flow cannot complete. The cause (typically BindException / address already in use) is attached as lastException.","triggerScenarios":"Calling the OAuth2 authorization-code flow where every configured callback port is already bound by another process (or blocked by permissions/firewall), so the ServerSocket bind fails for all ports in the list.","commonSituations":"Parallel test runs colliding on the same fixed callbackPort; a stale previous run's server still holding the port; running multiple suites on one CI host; port <1024 on Unix without privileges; corporate firewall blocking localhost binding in unusual setups.","solutions":["Free the conflicting process or choose free ports via callbackPorts (a list, so parallel runs can use distinct ports).","Check what holds the port: `lsof -i :<port>` (Unix) or `netstat -ano` (Windows), then stop it.","Register the chosen ports as redirect URIs (e.g. http://localhost:<port>/...) with your OAuth provider — an unregistered port fails later even if bound.","Avoid privileged ports (<1024) unless running with the required privileges."],"exampleFix":"// before\nkarate.configure('oauth', { callbackPort: 8080, /* ... */ });\n// after: give several fallback ports and ensure they're registered as redirect URIs\nkarate.configure('oauth', { callbackPorts: [9001, 9002, 9003], /* ... */ });","handlingStrategy":"validation","validationCode":"// before starting the OAuth flow, check the callback ports are bindable\nint[] ports = {9001, 9002};\nfor (int p : ports) {\n    try (var ss = new java.net.ServerSocket(p)) { /* ok */ }\n    catch (IOException e) { throw new IllegalStateException(\"callback port in use: \" + p); }\n}","typeGuard":null,"tryCatchPattern":"try {\n    auth.start(); // triggers redirectUri -> startCallbackServer\n} catch (OAuth2Exception e) {\n    // all callback ports failed to bind\n    throw new IllegalStateException(\"no free callback port among configured ports\", e.getCause());\n}","preventionTips":["Configure callbackPorts (a list) so parallel runs pick distinct ports.","Register every configured port as a redirect URI with the OAuth provider ahead of time.","Avoid fixed low-numbered ports shared across suites and services.","Clean up stale processes holding callback ports before test runs."],"tags":["oauth2","port-binding","callback-server","network"],"backgroundTag":"address-already-in-use","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"}