{"record":{"id":"7632f085be62c152","repo":"quarkusio/quarkus","slug":"the-s-can-only-be-set-to-false-if-s-is-not-s","errorCode":null,"errorMessage":"The '%s' can only be set to false if '%s' is not set. Either set '%s' to true or do not set '%s'.","messagePattern":"The '(.+?)' can only be set to false if '(.+?)' is not set\\. Either set '(.+?)' to true or do not set '(.+?)'\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java","lineNumber":349,"sourceCode":"        }\n\n        if (oidcConfig.token().verifyAccessTokenWithUserInfo().orElse(false)) {\n            if (!oidcConfig.discoveryEnabled().orElse(true)) {\n                if (oidcConfig.userInfoPath().isEmpty()) {\n                    throw new ConfigurationException(\n                            \"UserInfo path is missing but 'verifyAccessTokenWithUserInfo' is enabled\");\n                }\n                if (oidcConfig.introspectionPath().isPresent()) {\n                    throw new ConfigurationException(\n                            \"Introspection path is configured and 'verifyAccessTokenWithUserInfo' is enabled, these options are mutually exclusive\");\n                }\n            }\n        }\n\n        if (!oidcConfig.token().issuedAtRequired() && oidcConfig.token().age().isPresent()) {\n            String tokenIssuedAtRequired = getConfigPropertyForTenant(tenantId, \"token.issued-at-required\");\n            String tokenAge = getConfigPropertyForTenant(tenantId, \"token.age\");\n            throw new ConfigurationException(\n                    \"The '\" + tokenIssuedAtRequired + \"' can only be set to false if '\" + tokenAge + \"' is not set.\" +\n                            \" Either set '\" + tokenIssuedAtRequired + \"' to true or do not set '\" + tokenAge + \"'.\",\n                    Set.of(tokenIssuedAtRequired, tokenAge));\n        }\n\n        return createOidcProvider(oidcConfig).flatMap(p -> TenantConfigContext.createReady(p, oidcConfig));\n    }\n\n    private void verifyAllowedRoutes(OidcTenantConfig oidcConfig, String tenantId) {\n        if (!allowedRoutes.contains(OidcRoute.BACKCHANNEL_LOGOUT) && oidcConfig.logout().backchannel().path().isPresent()) {\n            LOG.warnf(\"'%s' is configured but the 'backchannel-logout' route is not in\"\n                    + \" 'quarkus.oidc.allowed-routes'; this tenant will not support back-channel logout\",\n                    getConfigPropertyForTenant(tenantId, \"logout.backchannel.path\"), tenantId);\n        }\n        if (!allowedRoutes.contains(OidcRoute.RESOURCE_METADATA) && oidcConfig.resourceMetadata().enabled()) {\n            LOG.warnf(\"'%s' is enabled but the 'resource-metadata' route is not in\"\n                    + \" 'quarkus.oidc.allowed-routes'; this tenant will not provide protected resource metadata\",\n                    getConfigPropertyForTenant(tenantId, \"resource-metadata.enabled\"), tenantId);","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java#L331-L367","documentation":"Token age verification compares the token's issued-at (iat) claim against token.age. If token.issued-at-required=false the iat claim is not required, making age checks meaningless and error-prone; Quarkus therefore forbids setting issued-at-required=false while token.age is present, reporting both properties in the ConfigurationException.","triggerScenarios":"token().issuedAtRequired() is false and token().age().isPresent() during createTenantContext; the exception carries a set of the two offending property names.","commonSituations":"Setting quarkus.oidc.token.issued-at-required=false to tolerate tokens without iat while also configuring token.age; provider issuing tokens without iat leads to conflicting tuning.","solutions":["Set quarkus.oidc.token.issued-at-required=true so age verification can rely on iat","Remove quarkus.oidc.token.age if iat cannot be guaranteed and age checks are not needed","Check per-tenant overrides (quarkus.oidc.<tenant>.token.*) for the conflicting pair"],"exampleFix":"// before\nquarkus.oidc.token.issued-at-required=false\nquarkus.oidc.token.age=5M\n// after\nquarkus.oidc.token.issued-at-required=true\nquarkus.oidc.token.age=5M","handlingStrategy":"validation","validationCode":"if (!config.token().issuedAtRequired() && config.token().age().isPresent()) {\n    throw new IllegalArgumentException(\"token.age requires token.issued-at-required=true\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep issued-at-required=true whenever token.age is configured","Only relax issued-at-required when iat checks are explicitly unwanted, and remove age together"],"tags":["quarkus","oidc","configuration","token-validation"],"backgroundTag":"oidc-dependent-config-missing","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}