quarkusio/quarkus · error · AuthenticationCompletionException

Authorization code flow access token which is required to ge

Error message

Authorization code flow access token which is required to get UserInfo is missing

What it means

During UserInfo verification (quarkus.oidc.authentication.user-info-required=true or verification enabled), the code flow access token from the request context is needed to call the UserInfo endpoint. This AuthenticationCompletionException is thrown when the request is an ID token request and no access token is present in the request data, so UserInfo cannot be fetched.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcIdentityProvider.java:831

            return Uni.createFrom().failure(t instanceof AuthenticationFailedException ? t
                    : new AuthenticationFailedException(t, tokenMap(request.getToken())));
        }
    }

    private Uni<UserInfo> getUserInfoUni(Map<String, Object> requestData, TokenAuthenticationRequest request,
            TenantConfigContext resolvedContext) {
        if (isInternalIdToken(request) && OidcUtils.cacheUserInfoInIdToken(tenantResolver, resolvedContext.oidcConfig())) {
            JsonObject userInfo = OidcCommonUtils.decodeJwtContent(request.getToken().getToken())
                    .getJsonObject(OidcUtils.USER_INFO_ATTRIBUTE);
            if (userInfo != null) {
                return Uni.createFrom().item(new UserInfo(userInfo.encode()));
            }
        }

        LOG.debug("Requesting UserInfo");
        String contextAccessToken = (String) requestData.get(OidcConstants.ACCESS_TOKEN_VALUE);
        if (contextAccessToken == null && isIdToken(request)) {
            throw new AuthenticationCompletionException(
                    "Authorization code flow access token which is required to get UserInfo is missing");
        }
        final String accessToken = contextAccessToken != null ? contextAccessToken : request.getToken().getToken();

        UserInfoCache userInfoCache = tenantResolver.getUserInfoCache();
        Uni<UserInfo> userInfoUni = userInfoCache == null ? null
                : userInfoCache.getUserInfo(accessToken, resolvedContext.oidcConfig(), getUserInfoRequestContext);
        if (userInfoUni == null) {
            userInfoUni = newUserInfoUni(resolvedContext, accessToken);
        } else {
            userInfoUni = userInfoUni.onItem().ifNull()
                    .switchTo(new Supplier<Uni<? extends UserInfo>>() {
                        @Override
                        public Uni<UserInfo> get() {
                            return newUserInfoUni(resolvedContext, accessToken);
                        }
                    });
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Request the 'openid' scope (and keep response_type=code) so an access token is issued and stored in the session.
  2. Disable UserInfo verification if not needed: remove quarkus.oidc.authentication.user-info-required / set verify-access-token-with-user-info=false.
  3. Check that the session cookie still contains the access token (encryption keys unchanged, cookie not truncated).
  4. Verify the tenant configuration matches the flow actually used (Bearer vs code flow).

Example fix

// before: ID-token-only config with UserInfo verification
quarkus.oidc.authentication.user-info-required=true
// after: request access token via proper code flow
quarkus.oidc.authentication.scopes=openid,profile
quarkus.oidc.token.verify-access-token-with-user-info=true
Defensive patterns

Strategy: validation

Validate before calling

if (userInfoRequired && isIdTokenRequest && requestData.get(OidcConstants.ACCESS_TOKEN_VALUE) == null) {
    throw new IllegalStateException("Code flow access token required for UserInfo; ensure scopes=openid and code flow completes");
}

Type guard

boolean hasAccessTokenForUserInfo(RoutingContext ctx) {
    return ctx.session().get(OidcConstants.ACCESS_TOKEN_VALUE) != null;
}

Try / catch

try {
    return completeAuthentication();
} catch (AuthenticationCompletionException e) {
    // redirect user back to the OIDC provider to redo the code flow
}

Prevention

When it happens

Trigger: quarkus.oidc.token.verify-access-token-with-user-info or userinfoRequired enabled while authentication completed with only an ID token and no access token stored in the TokenAuthenticationRequest context (e.g. session cookie lacking the access token).

Common situations: Enabling UserInfo verification on tenants that only receive ID tokens; upgrading Quarkus where strict code-flow token checks became stricter; misconfigured session encryption dropping the access token from the cookie.

Related errors


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