{"record":{"id":"e63f44d26d58081b","repo":"apache/pulsar","slug":"unsupported-algorithm","errorCode":"UNSUPPORTED_ALGORITHM","errorMessage":"PublicKey algorithm cannot be null","messagePattern":"PublicKey algorithm cannot be null","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-auth-oidc/src/main/java/org/apache/pulsar/broker/authentication/oidc/AuthenticationProviderOpenID.java","lineNumber":409,"sourceCode":"        }\n    }\n\n    /**\n     * Build and return a validator for the parameters.\n     *\n     * @param publicKey - the public key to use when configuring the validator\n     * @param publicKeyAlg - the algorithm for the parameterized public key\n     * @param jwt - jwt to be verified and returned (only if verified)\n     * @return a validator to use for validating a JWT associated with the parameterized public key.\n     * @throws AuthenticationException if the Public Key's algorithm is not supported or if the algorithm param does not\n     * match the Public Key's actual algorithm.\n     */\n    DecodedJWT verifyJWT(PublicKey publicKey,\n                                String publicKeyAlg,\n                                DecodedJWT jwt) throws AuthenticationException {\n        if (publicKeyAlg == null) {\n            incrementFailureMetric(AuthenticationExceptionCode.UNSUPPORTED_ALGORITHM);\n            throw new AuthenticationException(\"PublicKey algorithm cannot be null\");\n        }\n\n        Algorithm alg;\n        try {\n            switch (publicKeyAlg) {\n                case ALG_RS256:\n                    alg = Algorithm.RSA256((RSAPublicKey) publicKey, null);\n                    break;\n                case ALG_RS384:\n                    alg = Algorithm.RSA384((RSAPublicKey) publicKey, null);\n                    break;\n                case ALG_RS512:\n                    alg = Algorithm.RSA512((RSAPublicKey) publicKey, null);\n                    break;\n                case ALG_ES256:\n                    alg = Algorithm.ECDSA256((ECPublicKey) publicKey, null);\n                    break;\n                case ALG_ES384:","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-auth-oidc/src/main/java/org/apache/pulsar/broker/authentication/oidc/AuthenticationProviderOpenID.java#L391-L427","documentation":"verifyJWT needs to build a java-jwt Algorithm from the configured public key algorithm name, but publicKeyAlg is null, so no verifier can be constructed. It throws AuthenticationException(UNSUPPORTED_ALGORITHM) and records a failure metric before any signature verification happens.","triggerScenarios":"authenticateToken() calls verifyJWT() with publicKeyAlg == null, which happens when the algorithm name in the fetched JWKS key entry is missing or when the code that resolved the key from the JWKS/keystore failed to map the 'alg' parameter.","commonSituations":"The OIDC provider's JWKS endpoint returns a key without an 'alg' field (only 'kty'); broker cache/keystore stores keys without algorithm metadata; a custom subclass or test constructs the provider without setting the public key algorithm property.","solutions":["Check the JWKS response of your OIDC issuer: ensure each key has an 'alg' (and 'kid') field; if missing, upgrade/reconfigure the identity provider to include alg in its JWKS","Verify the broker's oidc configuration (discovery/issuer URL) points at a standards-compliant provider so keys are fetched with their algorithms","If keys come from a keystore, ensure the algorithm name is set alongside the key when loaded","Upgrade the broker to a version whose JWKS parsing defaults kty->alg (e.g., RSA->RS256) if your provider omits alg"],"exampleFix":"// before: JWKS entry without alg consumed as-is\n{\"kty\":\"RSA\",\"n\":\"...\",\"e\":\"AQAB\",\"kid\":\"k1\"}\n// after: reconfigure IdP to publish alg\n{\"kty\":\"RSA\",\"alg\":\"RS256\",\"n\":\"...\",\"e\":\"AQAB\",\"kid\":\"k1\"}","handlingStrategy":"validation","validationCode":"// validate JWKS entries before use\nJsonObject key = jwks.getJsonObject(i);\nif (key.getString(\"alg\") == null) {\n    throw new IllegalStateException(\"JWKS key '\" + key.getString(\"kid\") + \"' lacks alg field\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return verifyJWT(publicKey, publicKeyAlg, jwt);\n} catch (AuthenticationException e) {\n    if (e.getMessage().contains(\"algorithm cannot be null\")) {\n        log.error(\"Public key algorithm not resolved; check IdP JWKS/keystore config\");\n    }\n    throw e;\n}","preventionTips":["Use an identity provider whose JWKS publishes 'alg' for every key","Validate JWKS payloads during broker startup and fail fast on missing alg","Keep broker OIDC discovery configuration accurate and testable","Pin and test the IdP version; check release notes for JWKS format changes"],"tags":["auth","oidc","jwt","algorithm","configuration"],"backgroundTag":"unsupported-jwt-algorithm","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}