{"record":{"id":"ab1a083c31f025e3","repo":"quarkusio/quarkus","slug":"neither-public-key-nor-certificate-chain-verificat","errorCode":null,"errorMessage":"Neither public key nor certificate chain verification modes are enabled","messagePattern":"Neither public key nor certificate chain verification modes are enabled","errorType":"console","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java","lineNumber":132,"sourceCode":"        this.audience = checkAudienceProp();\n        this.requiredClaims = checkRequiredClaimsProp();\n        this.requiredAlgorithmConstraints = checkSignatureAlgorithm();\n        this.customValidators = customValidators == null ? List.of() : customValidators;\n        if (client != null) {\n            this.client.setOidcProvider(this);\n        }\n    }\n\n    public OidcProvider(String publicKeyEnc, OidcTenantConfig oidcConfig) {\n        this.client = null;\n        this.oidcConfig = oidcConfig;\n        this.tokenCustomizer = TenantFeatureFinder.find(oidcConfig);\n        if (publicKeyEnc != null) {\n            this.asymmetricKeyResolver = new LocalPublicKeyResolver(publicKeyEnc);\n        } else if (oidcConfig.certificateChain().trustStoreFile().isPresent()) {\n            this.asymmetricKeyResolver = new CertChainPublicKeyResolver(oidcConfig);\n        } else {\n            throw new IllegalStateException(\"Neither public key nor certificate chain verification modes are enabled\");\n        }\n        this.keyResolverProvider = null;\n        this.issuer = checkIssuerProp();\n        this.audience = checkAudienceProp();\n        this.requiredClaims = checkRequiredClaimsProp();\n        this.requiredAlgorithmConstraints = checkSignatureAlgorithm();\n        this.customValidators = TenantFeatureFinder.find(oidcConfig, Validator.class);\n    }\n\n    private AlgorithmConstraints checkSignatureAlgorithm() {\n        if (oidcConfig != null && oidcConfig.token().signatureAlgorithm().isPresent()) {\n            String configuredAlg = oidcConfig.token().signatureAlgorithm().get().getAlgorithm();\n            return new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, configuredAlg);\n        } else {\n            return null;\n        }\n    }\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java#L114-L150","documentation":"OidcProvider constructed for local (offline) JWT verification requires either a public key (quarkus.oidc.public-key) or a certificate chain trust store. This IllegalStateException is thrown from the constructor when neither is configured, meaning there is no key material to verify token signatures.","triggerScenarios":"Creating OidcProvider with oidcConfig that has neither publicKeyEnc (quarkus.oidc.public-key) nor quarkus.oidc.certificate-chain.trust-store-file set, i.e. local verification enabled without any verification key.","commonSituations":"Copy-pasted config where public-key line was removed; signing JWTs locally in tests without setting the key; typo in config property names so neither option resolves.","solutions":["Set quarkus.oidc.public-key=<PEM key> matching the token signing key.","Or set quarkus.oidc.certificate-chain.trust-store-file (and related trust-store options) for certificate chain verification.","Or remove local-verification-only setup and point the tenant at a real OIDC provider (auth-server-url) so keys come from JWKS.","Verify the config properties are on the correct tenant profile (quarkus.oidc.<tenant>.public-key)."],"exampleFix":"// before\n# quarkus.oidc.public-key= (missing)\n// after\nquarkus.oidc.public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...","handlingStrategy":"validation","validationCode":"if (config.publicKey().isEmpty() && config.certificateChain().trustStoreFile().isEmpty()) {\n    throw new IllegalStateException(\"Set quarkus.oidc.public-key or certificate-chain.trust-store-file for local verification\");\n}","typeGuard":"boolean canVerifyLocally(OidcTenantConfig cfg) {\n    return cfg.publicKey().isPresent()\n        || cfg.certificateChain().trustStoreFile().isPresent();\n}","tryCatchPattern":"try {\n    return new OidcProvider(oidcConfig, tenantResolver);\n} catch (IllegalStateException e) {\n    // fail fast at startup: log and abort deployment\n}","preventionTips":["Provide the signing public key (quarkus.oidc.public-key) whenever doing local JWT verification","Or use certificate chain verification with a configured trust store","Prefer auth-server-url + JWKS-based verification over hardcoded keys to avoid this entirely"],"tags":["oidc","configuration","jwt-signature","public-key"],"backgroundTag":"missing-verification-key-config","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"}