{"record":{"id":"38c9df38a7f23ed1","repo":"spring-projects/spring-security","slug":"failed-to-encode-the-jwt-due-to-signing-error-fai-38c9df","errorCode":null,"errorMessage":"Failed to encode the JWT due to signing error: Failed to create a JWS Signer -> + ex.getMessage()","messagePattern":"Failed to encode the JWT due to signing error: Failed to create a JWS Signer -> \\+ ex\\.getMessage\\(\\)","errorType":"exception","errorClass":"JwtEncodingException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtEncoder.java","lineNumber":283,"sourceCode":"\t\t}\n\n\t\tJwsHeader.Builder headersBuilder = JwsHeader.from(headers);\n\t\tif (!StringUtils.hasText(headers.getKeyId()) && StringUtils.hasText(jwk.getKeyID())) {\n\t\t\theadersBuilder.keyId(jwk.getKeyID());\n\t\t}\n\t\tif (!StringUtils.hasText(headers.getX509SHA256Thumbprint()) && jwk.getX509CertSHA256Thumbprint() != null) {\n\t\t\theadersBuilder.x509SHA256Thumbprint(jwk.getX509CertSHA256Thumbprint().toString());\n\t\t}\n\n\t\treturn headersBuilder.build();\n\t}\n\n\tprivate static JWSSigner createSigner(JWK jwk) {\n\t\ttry {\n\t\t\treturn JWS_SIGNER_FACTORY.createJWSSigner(jwk);\n\t\t}\n\t\tcatch (JOSEException ex) {\n\t\t\tthrow new JwtEncodingException(String.format(ENCODING_ERROR_MESSAGE_TEMPLATE,\n\t\t\t\t\t\"Failed to create a JWS Signer -> \" + ex.getMessage()), ex);\n\t\t}\n\t}\n\n\tprivate static JWSHeader convert(JwsHeader headers) {\n\t\tJwsAlgorithm algorithm = headers.getAlgorithm();\n\t\tAssert.notNull(algorithm, \"JWS header algorithm must not be null\");\n\t\tJWSHeader.Builder builder = new JWSHeader.Builder(JWSAlgorithm.parse(algorithm.getName()));\n\n\t\tif (headers.getJwkSetUrl() != null) {\n\t\t\tbuilder.jwkURL(convertAsURI(JoseHeaderNames.JKU, headers.getJwkSetUrl()));\n\t\t}\n\n\t\tMap<String, Object> jwk = headers.getJwk();\n\t\tif (!CollectionUtils.isEmpty(jwk)) {\n\t\t\ttry {\n\t\t\t\tbuilder.jwk(JWK.parse(jwk));\n\t\t\t}","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtEncoder.java#L265-L301","documentation":"NimbusJwtEncoder.createSigner() calls the nimbus-jose-jwt JWS signer factory to build a JWSSigner for the selected JWK and wraps any JOSEException in a JwtEncodingException. This fires before signing ever starts: the factory cannot construct a signer for the given key type/algorithm combination at all. It typically means the JWK's key type is incompatible with the requested JWS algorithm or the key material is invalid.","triggerScenarios":"NimbusJwtEncoder.encode(...) where the JWKSource resolves a JWK that the JWSAlgorithmFactory cannot handle: e.g. requesting ES256 while the resolved JWK is an RSAKey, an OctetSequenceKey with an empty/invalid secret bytes, or a JWK missing required fields (no modulus/exponent, no EC curve parameter) so createJWSSigner throws.","commonSituations":"JWKSource returning keys of a different type than the configured jwsAlgorithm; hand-rolled JWK JSON parsed with missing parameters; OctetSequenceKey built with a null or too-short secret; changing the algorithm in JwtEncoderParameters without updating the keystore; loading keys from a vault/KMS where the export drops required fields.","solutions":["Check the wrapped exception via getCause(): it states why the signer could not be created (unsupported algorithm/key pair).","Align the JwsAlgorithm in JwsHeader (or EncoderParameters claims) with the key type your JWKSource actually serves — inspect the JWK with jwk.getKeyType() and jwk.getAlgorithm().","Rebuild the JWK ensuring required parameters exist: for RSAKey provide modulus+exponent (or KeyPair), for ECKey provide curve+point, for OctetSequenceKey provide a full-length secret.","Test the JWK standalone with new NimbusRS256Signer / JWSAlgorithmFactory to confirm it can sign before wiring it into the JWKSource."],"exampleFix":"// before\nJWKSource<SecurityContext> jwkSource = (jwkSelector, ctx) ->\n    List.of(rsaKey); // algorithm requested: ES256\n// after\nECKey ecKey = new ECKeyGenerator(Curve.P_256).keyID(\"k1\").generate();\nJWKSource<SecurityContext> jwkSource = (jwkSelector, ctx) ->\n    jwkSelector.select(List.of(ecKey)); // matches ES256","handlingStrategy":"validation","validationCode":"// before registering the JWKSource\nJWSAlgorithm alg = (JWSAlgorithm) jwsHeader.getAlgorithm();\nif (!JWSAlgorithm.Family.SIGNATURE.contains(alg)\n        || !jwk.getKeyType().getValue().equals(expectedKeyTypeFor(alg))) {\n    throw new IllegalStateException(\"JWK type \" + jwk.getKeyType() + \" unsupported for \" + alg);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return jwtEncoder.encode(parameters);\n} catch (JwtEncodingException ex) {\n    throw new TokenSigningException(\"Signer creation failed for JWK \" + jwkId, ex.getCause());\n}","preventionTips":["Derive the JwsHeader algorithm from the JWK itself (jwk.getAlgorithm()) instead of hardcoding it.","Validate loaded keys at boot: attempt JWS_SIGNER_FACTORY.createJWSSigner(jwk) in a health check.","When rotating keys, regenerate the full key pair/secret rather than editing individual JWK fields.","Restrict your JWKSource selector to keys matching the required algorithm."],"tags":["jwt","signing","spring-security","jwk","algorithm-mismatch"],"backgroundTag":"incompatible-source-type","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}