quarkusio/quarkus · error · io.quarkus.oidc.runtime.OIDCException

Authorization server must generate a request URI, but got %s

Error message

Authorization server must generate a request URI, but got %s

What it means

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.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProviderClientImpl.java:313

                        .filterHttpResponse(requestProps, resp, responseFilters, PUSHED_AUTHORIZATION_REQUEST)
                        .flatMap(buffer -> {
                            if (resp.statusCode() == 201) {
                                JsonObject jsonObject = buffer.toJsonObject();
                                if (LOG.isDebugEnabled()) {
                                    LOG.debugf("Request succeeded: %s", OidcCommonUtils.maskJsonTokens(jsonObject));
                                }
                                return Uni.createFrom().item(jsonObject);
                            }
                            return Uni.createFrom()
                                    .failure(responseException(metadata.getPushedAuthorizationRequestUri(), resp, buffer));
                        }))
                .map(json -> {
                    final String requestUri = json.getString(OidcConstants.REQUEST_URI);
                    if (requestUri != null) {
                        return requestUri;
                    }
                    // should not happen, see https://datatracker.ietf.org/doc/html/rfc9126#name-successful-response
                    throw new OIDCException("Authorization server must generate a request URI, but got " + json);
                });
    }

    Uni<AuthorizationCodeTokens> getAuthorizationCodeTokens(String code, String redirectUri, String codeVerifier) {
        final MultiMap codeGrantParams = MultiMap.caseInsensitiveMultiMap();
        codeGrantParams.add(OidcConstants.GRANT_TYPE, OidcConstants.AUTHORIZATION_CODE);
        codeGrantParams.add(OidcConstants.CODE_FLOW_CODE, code);
        codeGrantParams.add(OidcConstants.CODE_FLOW_REDIRECT_URI, redirectUri);
        if (codeVerifier != null) {
            codeGrantParams.add(OidcConstants.PKCE_CODE_VERIFIER, codeVerifier);
        }
        if (oidcConfig.codeGrant().extraParams() != null) {
            codeGrantParams.addAll(oidcConfig.codeGrant().extraParams());
        }
        final OidcRequestContextProperties requestProps = getRequestProps(OidcConstants.AUTHORIZATION_CODE);
        return getHttpResponse(requestProps, metadata.getTokenUri(), codeGrantParams, TokenOperation.GET,
                OidcEndpoint.Type.TOKEN)
                .transformToUni(resp -> getAuthorizationCodeTokens(requestProps, resp));

View on GitHub (pinned to e1c734241f)

Solutions

  1. Confirm the authorization server supports RFC 9126 PAR (Keycloak 15+/recent Ping, Auth0 etc.); upgrade the server if not
  2. Disable PAR: remove quarkus.oidc.authentication.pushed-authorization-request-enabled (or set it false) to use the classic authorization-code flow
  3. Check for proxies/CDNs rewriting the response and bypass them
  4. Capture the raw PAR response (quarkus logs / HTTP client) to see the actual JSON returned

Example fix

# before
quarkus.oidc.authentication.pushed-authorization-request-enabled=true
# after (server lacks PAR support)
quarkus.oidc.authentication.pushed-authorization-request-enabled=false
Defensive patterns

Strategy: try-catch

Validate before calling

// feature-detect PAR support: issue a probe PAR and check request_uri in the response
if (!parResponseJson.containsKey("request_uri")) {
    // server does not conform to RFC 9126; fall back to standard flow
}

Type guard

boolean hasRequestUri(JsonObject parResponse) {
    return parResponse != null && parResponse.getString("request_uri") != null;
}

Try / catch

try {
    return client.pushedAuthorizationRequest(...);
} catch (OIDCException e) {
    if (e.getMessage().contains("request URI")) {
        // fall back to classic authorization code flow
        return classicAuthorizeRedirect();
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/df1b036aae442d86. Report an issue: GitHub.