{"record":{"id":"df1b036aae442d86","repo":"quarkusio/quarkus","slug":"authorization-server-must-generate-a-request-uri","errorCode":null,"errorMessage":"Authorization server must generate a request URI, but got %s","messagePattern":"Authorization server must generate a request URI, but got (.+?)","errorType":"exception","errorClass":"io.quarkus.oidc.runtime.OIDCException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProviderClientImpl.java","lineNumber":313,"sourceCode":"                        .filterHttpResponse(requestProps, resp, responseFilters, PUSHED_AUTHORIZATION_REQUEST)\n                        .flatMap(buffer -> {\n                            if (resp.statusCode() == 201) {\n                                JsonObject jsonObject = buffer.toJsonObject();\n                                if (LOG.isDebugEnabled()) {\n                                    LOG.debugf(\"Request succeeded: %s\", OidcCommonUtils.maskJsonTokens(jsonObject));\n                                }\n                                return Uni.createFrom().item(jsonObject);\n                            }\n                            return Uni.createFrom()\n                                    .failure(responseException(metadata.getPushedAuthorizationRequestUri(), resp, buffer));\n                        }))\n                .map(json -> {\n                    final String requestUri = json.getString(OidcConstants.REQUEST_URI);\n                    if (requestUri != null) {\n                        return requestUri;\n                    }\n                    // should not happen, see https://datatracker.ietf.org/doc/html/rfc9126#name-successful-response\n                    throw new OIDCException(\"Authorization server must generate a request URI, but got \" + json);\n                });\n    }\n\n    Uni<AuthorizationCodeTokens> getAuthorizationCodeTokens(String code, String redirectUri, String codeVerifier) {\n        final MultiMap codeGrantParams = MultiMap.caseInsensitiveMultiMap();\n        codeGrantParams.add(OidcConstants.GRANT_TYPE, OidcConstants.AUTHORIZATION_CODE);\n        codeGrantParams.add(OidcConstants.CODE_FLOW_CODE, code);\n        codeGrantParams.add(OidcConstants.CODE_FLOW_REDIRECT_URI, redirectUri);\n        if (codeVerifier != null) {\n            codeGrantParams.add(OidcConstants.PKCE_CODE_VERIFIER, codeVerifier);\n        }\n        if (oidcConfig.codeGrant().extraParams() != null) {\n            codeGrantParams.addAll(oidcConfig.codeGrant().extraParams());\n        }\n        final OidcRequestContextProperties requestProps = getRequestProps(OidcConstants.AUTHORIZATION_CODE);\n        return getHttpResponse(requestProps, metadata.getTokenUri(), codeGrantParams, TokenOperation.GET,\n                OidcEndpoint.Type.TOKEN)\n                .transformToUni(resp -> getAuthorizationCodeTokens(requestProps, resp));","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProviderClientImpl.java#L295-L331","documentation":"Thrown by OidcProviderClientImpl.pushedAuthorizationRequest when the OIDC authorization server responds successfully to a Pushed Authorization Request (PAR, RFC 9126) but the response JSON lacks the required 'request_uri' field. The spec guarantees 'request_uri' on success, so its absence means the server is non-conformant or returned an unexpected body, and an OIDCException is thrown.","triggerScenarios":"Calling the pushed authorization request flow (quarkus.oidc.authentication.pushed-authorization-request-enabled=true) while the authorization server returns a 200 whose JSON body has no 'request_uri' property.","commonSituations":"Using an authorization server (older Keycloak versions, some gateways) that doesn't actually support PAR despite the endpoint existing; a proxy/API gateway stripping or rewriting the response body; a non-standard PAR implementation returning a different field name.","solutions":["Confirm the authorization server supports RFC 9126 PAR (Keycloak 15+/recent Ping, Auth0 etc.); upgrade the server if not","Disable PAR: remove quarkus.oidc.authentication.pushed-authorization-request-enabled (or set it false) to use the classic authorization-code flow","Check for proxies/CDNs rewriting the response and bypass them","Capture the raw PAR response (quarkus logs / HTTP client) to see the actual JSON returned"],"exampleFix":"# before\nquarkus.oidc.authentication.pushed-authorization-request-enabled=true\n# after (server lacks PAR support)\nquarkus.oidc.authentication.pushed-authorization-request-enabled=false","handlingStrategy":"try-catch","validationCode":"// feature-detect PAR support: issue a probe PAR and check request_uri in the response\nif (!parResponseJson.containsKey(\"request_uri\")) {\n    // server does not conform to RFC 9126; fall back to standard flow\n}","typeGuard":"boolean hasRequestUri(JsonObject parResponse) {\n    return parResponse != null && parResponse.getString(\"request_uri\") != null;\n}","tryCatchPattern":"try {\n    return client.pushedAuthorizationRequest(...);\n} catch (OIDCException e) {\n    if (e.getMessage().contains(\"request URI\")) {\n        // fall back to classic authorization code flow\n        return classicAuthorizeRedirect();\n    }\n    throw e;\n}","preventionTips":["Verify RFC 9126 support (Keycloak 15+, current commercial IdPs) before enabling PAR","Test the PAR endpoint manually with curl during setup","Watch for proxies that alter authorization-server response bodies"],"tags":["oidc","par","authorization-server","rfc9126"],"backgroundTag":"oidc-provider-response-invalid","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}