{"record":{"id":"1b966e0acf0bb26a","repo":"alibaba/nacos","slug":"failed-to-discover-oidc-configuration-status","errorCode":null,"errorMessage":"Failed to discover OIDC configuration, status: ","messagePattern":"Failed to discover OIDC configuration, status: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/config/OidcProviderMetadataProvider.java","lineNumber":95,"sourceCode":"        return result;\n    }\n    \n    @SuppressWarnings(\"unchecked\")\n    private OidcProviderMetadata discover() throws IOException {\n        String issuerUri = config.getIssuerUri();\n        if (StringUtils.isBlank(issuerUri)) {\n            throw new IOException(\"Issuer URI is not configured\");\n        }\n        String discoveryUrl = trimTrailingSlash(issuerUri)\n            + OidcProtocolConstants.WELL_KNOWN_PATH;\n        LOGGER.info(\"Discovering OIDC configuration from: {}\", discoveryUrl);\n        try {\n            HttpRequest request = HttpRequest.newBuilder().uri(URI.create(discoveryUrl))\n                .header(\"Accept\", \"application/json\").timeout(DISCOVERY_TIMEOUT).GET().build();\n            HttpResponse<String> response =\n                httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != OidcProtocolConstants.HTTP_STATUS_OK) {\n                throw new IOException(\"Failed to discover OIDC configuration, status: \"\n                    + response.statusCode());\n            }\n            Map<String, Object> values = JsonUtils.toObj(response.body(), Map.class);\n            if (values == null) {\n                throw new IOException(\"OIDC discovery response is empty\");\n            }\n            OidcProviderMetadata result = new OidcProviderMetadata(\n                stringValue(values, OidcProtocolConstants.DISCOVERY_AUTHORIZATION_ENDPOINT),\n                stringValue(values, OidcProtocolConstants.DISCOVERY_TOKEN_ENDPOINT),\n                stringValue(values, OidcProtocolConstants.DISCOVERY_USERINFO_ENDPOINT),\n                stringValue(values, OidcProtocolConstants.DISCOVERY_END_SESSION_ENDPOINT),\n                stringValue(values, OidcProtocolConstants.DISCOVERY_JWKS_URI));\n            LOGGER.info(\"OIDC configuration discovered: jwksUri={}\", result.getJwksUri());\n            return result;\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IOException(\"OIDC discovery interrupted\", e);\n        } catch (IOException e) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/config/OidcProviderMetadataProvider.java#L77-L113","documentation":"Thrown when the OIDC discovery HTTP GET to <issuer-uri>/.well-known/openid-configuration returns a non-200 status code. The actual status code is appended. This is an IdP-side or connectivity failure, not a Nacos config error (the URL was buildable).","triggerScenarios":"getMetadata() triggers discover(); the discovery endpoint responds 404 (wrong issuer path), 401/403 (auth-required discovery), 500 (IdP error), or the host returns a redirect/gateway error.","commonSituations":"issuer-uri points to a path where discovery doesn't exist (404); IdP is down or behind a misconfigured proxy (502/503); discovery endpoint requires authentication; corporate proxy/firewall blocks the outbound request.","solutions":["curl the discovery URL yourself and read the appended status code: GET <issuer-uri>/.well-known/openid-configuration.","For 404: correct issuer-uri to the OIDC issuer root (often the realm base URL for Keycloak).","For 5xx: check IdP health and any reverse proxy between Nacos and the IdP.","For 401/403: ensure the discovery endpoint is public per OIDC spec, or whitelist Nacos.","Verify outbound HTTPS connectivity and DNS resolution from the Nacos host."],"exampleFix":"// before: issuer path has no discovery doc (returns 404)\nnacos.plugin.auth.oidc.issuer-uri=https://keycloak.example.com\n// after: point at the realm root that serves .well-known/openid-configuration\nnacos.plugin.auth.oidc.issuer-uri=https://keycloak.example.com/realms/myrealm","handlingStrategy":"retry","validationCode":"// Pre-flight: probe the discovery URL reachability before relying on it\nString url = issuerUri.replaceAll(\"/+$\", \"\") + \"/.well-known/openid-configuration\";\n// (manual curl or an HttpClient probe returning the status code)","typeGuard":null,"tryCatchPattern":"try {\n    metadataProvider.getMetadata();\n} catch (IOException e) {\n    if (e.getMessage().contains(\"status:\")) {\n        // transient IdP/network issue — back off and retry a limited number of times\n        log.warn(\"OIDC discovery returned non-200; will retry: {}\", e.getMessage());\n        retryWithBackoff(() -> metadataProvider.getMetadata(), 3);\n    } else {\n        throw e;\n    }\n}","preventionTips":["curl the discovery URL from the Nacos host to confirm 200 before going live.","Keep issuer-uri pointed at the OIDC issuer root (e.g. Keycloak realm base).","Ensure DNS/firewall/proxy allows outbound HTTPS to the IdP."],"tags":["oidc","network","discovery","idp-error"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}