{"record":{"id":"9e393cbbb7023a49","repo":"quarkusio/quarkus","slug":"state-cookie-value-for-the-s-tenant-can-not-be-en","errorCode":null,"errorMessage":"State cookie value for the %s tenant can not be encrypted: %s","messagePattern":"State cookie value for the (.+?) tenant can not be encrypted: (.+?)","errorType":"exception","errorClass":"AuthenticationCompletionException","httpStatus":401,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java","lineNumber":1429,"sourceCode":"    private String encodeExtraStateValue(CodeAuthenticationStateBean extraStateValue, TenantConfigContext configContext) {\n        JsonObject json = new JsonObject();\n\n        if (extraStateValue.getCodeVerifier() != null || extraStateValue.getNonce() != null) {\n            if (extraStateValue.getCodeVerifier() != null) {\n                json.put(OidcConstants.PKCE_CODE_VERIFIER, extraStateValue.getCodeVerifier());\n            }\n            if (extraStateValue.getNonce() != null) {\n                json.put(OidcConstants.NONCE, extraStateValue.getNonce());\n            }\n            if (extraStateValue.getRestorePath() != null) {\n                json.put(OidcUtils.STATE_COOKIE_RESTORE_PATH, extraStateValue.getRestorePath());\n            }\n            try {\n                return OidcUtils.encryptJson(json, configContext.getStateCookieEncryptionKey());\n            } catch (Exception ex) {\n                LOG.errorf(\"State cookie value for the %s tenant can not be encrypted: %s\",\n                        configContext.oidcConfig().tenantId().get(), ex.getMessage());\n                throw new AuthenticationCompletionException(ex);\n            }\n        } else {\n            json.put(OidcUtils.STATE_COOKIE_RESTORE_PATH, extraStateValue.getRestorePath());\n\n            return Base64.getUrlEncoder().withoutPadding().encodeToString(json.encode().getBytes(StandardCharsets.UTF_8));\n        }\n\n    }\n\n    private String generatePostLogoutState(RoutingContext context, TenantConfigContext configContext) {\n        OidcUtils.removeCookie(context, configContext.oidcConfig(), getPostLogoutCookieName(configContext.oidcConfig()));\n        return OidcUtils.createCookie(context, configContext.oidcConfig(), getPostLogoutCookieName(configContext.oidcConfig()),\n                UUID.randomUUID().toString(),\n                60 * 30).getValue();\n    }\n\n    private String buildUri(RoutingContext context, boolean forceHttps, String path) {\n        if (path.startsWith(HTTP_SCHEME)) {","sourceCodeStart":1411,"sourceCodeEnd":1447,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java#L1411-L1447","documentation":"When the state cookie encryption key is configured, Quarkus encrypts the state cookie JSON before sending it to the browser. If OidcUtils.encryptJson fails (wrong key format/algorithm/JCE issue), the code flow cannot proceed securely, so an AuthenticationCompletionException wrapping the cause is thrown.","triggerScenarios":"OidcUtils.encryptJson(json, configContext.getStateCookieEncryptionKey()) throws while building the state cookie in CodeAuthenticationMechanism (state cookie encryption enabled via quarkus.oidc.token-state-manager.encryption or state cookie secret).","commonSituations":"State cookie encryption key set to an invalid length/format for the AES algorithm; different keys across cluster nodes (one node can't decrypt, but encrypt-side misconfig also fails here); JDK without required JCE policy; key containing whitespace/encoding artifacts from env substitution.","solutions":["Check the logged ex.getMessage() for the underlying crypto error and fix the key format (a base64-encoded key of the required AES length, e.g. 16/24/32 bytes).","Regenerate the key: openssl rand -base64 32 and set it as the state cookie encryption secret.","Ensure all nodes in the cluster share the identical, valid key.","Alternatively, disable state cookie encryption if your security posture allows unencrypted (still signed/encoded) state cookies."],"exampleFix":"// before\nquarkus.oidc.state-cookie-encryption-key=my-secret\n// after\nquarkus.oidc.state-cookie-encryption-key=<base64 of 32 random bytes>","handlingStrategy":"validation","validationCode":"String key = System.getenv(\"QUARKUS_OIDC_STATE_COOKIE_ENCRYPTION_KEY\");\nbyte[] raw = Base64.getDecoder().decode(key);\nif (raw.length != 16 && raw.length != 24 && raw.length != 32) {\n    throw new IllegalStateException(\"State cookie encryption key must be base64 of 16/24/32 bytes, got \" + raw.length);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return buildStateCookie(state);\n} catch (AuthenticationCompletionException e) {\n    if (e.getCause() != null) {\n        log.errorf(\"State cookie encryption failed: %s; check key format/length\", e.getCause().getMessage());\n    }\n    throw e;\n}","preventionTips":["Generate keys with `openssl rand -base64 32` and store them in a secret manager.","Ensure identical keys on every cluster node.","Validate key material (length, base64 encoding) in a startup health check.","Beware of shell/env quoting adding whitespace to the key value."],"tags":["oidc","state-cookie","encryption","code-flow"],"backgroundTag":"cookie-encryption-failed","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"}