{"record":{"id":"07bc86e4b0b9554f","repo":"conductor-oss/conductor","slug":"failed-to-acquire-oauth-token-from-tokenendpointu","errorCode":null,"errorMessage":"Failed to acquire OAuth token from {tokenEndpointUrl}","messagePattern":"Failed to acquire OAuth token from (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/agent/credentials/OAuthTokenProvider.java","lineNumber":102,"sourceCode":"                        .add(\"grant_type\", \"client_credentials\")\n                        .add(\"client_id\", clientId)\n                        .add(\"client_secret\", clientSecret)\n                        .add(\"scope\", scope)\n                        .build();\n\n        Request request = new Request.Builder().url(tokenEndpointUrl).post(body).build();\n\n        try (Response response = httpClient.newCall(request).execute()) {\n            if (!response.isSuccessful() || response.body() == null) {\n                throw new RuntimeException(\"OAuth token request failed: HTTP \" + response.code());\n            }\n            JsonNode json = MAPPER.readTree(response.body().string());\n            cachedToken = json.get(\"access_token\").asText();\n            long expiresIn = json.has(\"expires_in\") ? json.get(\"expires_in\").asLong() : 3600L;\n            expiresAt = Instant.now().plusSeconds(expiresIn);\n            log.debug(\"OAuth token refreshed, expires at {}\", expiresAt);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Failed to acquire OAuth token from \" + tokenEndpointUrl, e);\n        }\n    }\n}\n","sourceCodeStart":84,"sourceCodeEnd":106,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/agent/credentials/OAuthTokenProvider.java#L84-L106","documentation":"Thrown by OAuthTokenProvider.refresh when the HTTP request to the token endpoint raises an IOException (caught in the same try block). The original IOException is wrapped as the cause of this RuntimeException, and the message echoes the tokenEndpointUrl. Unlike error 142 (an HTTP status rejection by the IdP), this is a transport-level failure: the request never completed.","triggerScenarios":"Network-layer failure reaching the token endpoint: DNS cannot resolve the host, connection refused/timeout, TLS handshake failure (expired CA, untrusted cert), a proxy/firewall blocking egress, or the OkHttpClient misconfigured with too-short timeouts.","commonSituations":"Running in a locked-down network/VPC without an egress allow-rule for login.microsoftonline.com; a corporate MITM proxy whose CA is not in the JVM truststore; the tokenEndpointUrl host typo; intermittent connectivity in CI containers.","solutions":["Inspect the wrapped cause (getCause()) — UnknownHostException means DNS, SSLHandshakeException means cert/trust, SocketTimeoutException means timeout/egress.","Add an egress allow-rule / proxy for the token endpoint host on the host/container/VPC.","If behind a TLS-intercepting proxy, import the proxy's root CA into the JVM truststore (or the OkHttpClient used by OAuthTokenProvider).","Increase connect/read timeouts on the OkHttpClient passed into OAuthTokenProvider if the IdP is slow."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Validate egress reachability at startup (conceptual)\n// InetSocketAddress.createUnresolved(host, 443) + a connect probe belongs in a health check","typeGuard":null,"tryCatchPattern":"// Network/transport failures are often transient — retry with backoff\nint attempts = 0;\nwhile (true) {\n    try {\n        return tokenProvider.getToken();\n    } catch (RuntimeException e) {\n        if (!(e.getCause() instanceof java.io.IOException) || ++attempts >= MAX_ATTEMPTS) throw e;\n        backoff(attempts);\n    }\n}","preventionTips":["Configure an egress allow-rule for the token endpoint host in every environment.","If behind a TLS-intercepting proxy, add its root CA to the JVM/OkHttp truststore.","Set generous connect/read timeouts on the OkHttpClient passed to OAuthTokenProvider."],"tags":["oauth","auth","network","ioexception","transport","credentials"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}