{"record":{"id":"02497522ba383b4b","repo":"quarkusio/quarkus","slug":"authorization-code-flow-access-token-which-is-requ","errorCode":null,"errorMessage":"Authorization code flow access token which is required to get UserInfo is missing","messagePattern":"Authorization code flow access token which is required to get UserInfo is missing","errorType":"exception","errorClass":"AuthenticationCompletionException","httpStatus":401,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcIdentityProvider.java","lineNumber":831,"sourceCode":"            return Uni.createFrom().failure(t instanceof AuthenticationFailedException ? t\n                    : new AuthenticationFailedException(t, tokenMap(request.getToken())));\n        }\n    }\n\n    private Uni<UserInfo> getUserInfoUni(Map<String, Object> requestData, TokenAuthenticationRequest request,\n            TenantConfigContext resolvedContext) {\n        if (isInternalIdToken(request) && OidcUtils.cacheUserInfoInIdToken(tenantResolver, resolvedContext.oidcConfig())) {\n            JsonObject userInfo = OidcCommonUtils.decodeJwtContent(request.getToken().getToken())\n                    .getJsonObject(OidcUtils.USER_INFO_ATTRIBUTE);\n            if (userInfo != null) {\n                return Uni.createFrom().item(new UserInfo(userInfo.encode()));\n            }\n        }\n\n        LOG.debug(\"Requesting UserInfo\");\n        String contextAccessToken = (String) requestData.get(OidcConstants.ACCESS_TOKEN_VALUE);\n        if (contextAccessToken == null && isIdToken(request)) {\n            throw new AuthenticationCompletionException(\n                    \"Authorization code flow access token which is required to get UserInfo is missing\");\n        }\n        final String accessToken = contextAccessToken != null ? contextAccessToken : request.getToken().getToken();\n\n        UserInfoCache userInfoCache = tenantResolver.getUserInfoCache();\n        Uni<UserInfo> userInfoUni = userInfoCache == null ? null\n                : userInfoCache.getUserInfo(accessToken, resolvedContext.oidcConfig(), getUserInfoRequestContext);\n        if (userInfoUni == null) {\n            userInfoUni = newUserInfoUni(resolvedContext, accessToken);\n        } else {\n            userInfoUni = userInfoUni.onItem().ifNull()\n                    .switchTo(new Supplier<Uni<? extends UserInfo>>() {\n                        @Override\n                        public Uni<UserInfo> get() {\n                            return newUserInfoUni(resolvedContext, accessToken);\n                        }\n                    });\n        }","sourceCodeStart":813,"sourceCodeEnd":849,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcIdentityProvider.java#L813-L849","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Request the 'openid' scope (and keep response_type=code) so an access token is issued and stored in the session.","Disable UserInfo verification if not needed: remove quarkus.oidc.authentication.user-info-required / set verify-access-token-with-user-info=false.","Check that the session cookie still contains the access token (encryption keys unchanged, cookie not truncated).","Verify the tenant configuration matches the flow actually used (Bearer vs code flow)."],"exampleFix":"// before: ID-token-only config with UserInfo verification\nquarkus.oidc.authentication.user-info-required=true\n// after: request access token via proper code flow\nquarkus.oidc.authentication.scopes=openid,profile\nquarkus.oidc.token.verify-access-token-with-user-info=true","handlingStrategy":"validation","validationCode":"if (userInfoRequired && isIdTokenRequest && requestData.get(OidcConstants.ACCESS_TOKEN_VALUE) == null) {\n    throw new IllegalStateException(\"Code flow access token required for UserInfo; ensure scopes=openid and code flow completes\");\n}","typeGuard":"boolean hasAccessTokenForUserInfo(RoutingContext ctx) {\n    return ctx.session().get(OidcConstants.ACCESS_TOKEN_VALUE) != null;\n}","tryCatchPattern":"try {\n    return completeAuthentication();\n} catch (AuthenticationCompletionException e) {\n    // redirect user back to the OIDC provider to redo the code flow\n}","preventionTips":["Always request the 'openid' scope so an access token is issued in code flow","Only enable UserInfo verification when your flow actually stores access tokens","Keep session cookie encryption keys stable so stored access tokens survive deployments"],"tags":["oidc","userinfo","authorization-code-flow","configuration"],"backgroundTag":"missing-access-token-for-userinfo","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"}