{"record":{"id":"1053b4a05d4a1e03","repo":"eclipse-vertx/vert.x","slug":"jwk-doesn-t-contain-seckey-material","errorCode":null,"errorMessage":"JWK doesn't contain secKey material","messagePattern":"JWK doesn't contain secKey material","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/internal/digest/DigitalSigningAlgorithm.java","lineNumber":107,"sourceCode":"  public boolean canSign() {\n    return privateKey != null;\n  }\n\n  @Override\n  public boolean canVerify() {\n    return publicKey != null;\n  }\n\n  // TODO : make this compliant\n  @Override\n  public String name() {\n    return alg;\n  }\n\n  @Override\n  public Signer signer() throws GeneralSecurityException {\n    if (privateKey == null) {\n      throw new IllegalStateException(\"JWK doesn't contain secKey material\");\n    }\n    Signature signature;\n    try {\n      signature = signatureFactory.call();\n    } catch (Exception e) {\n      throw new GeneralSecurityException(e);\n    }\n    return payload -> {\n      signature.initSign(privateKey);\n      signature.update(payload);\n      return signature.sign();\n    };\n  }\n\n  @Override\n  public Verifier verifier() throws GeneralSecurityException {\n    if (publicKey == null) {\n      throw new IllegalStateException(\"JWK doesn't contain pubKey material\");","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/internal/digest/DigitalSigningAlgorithm.java#L89-L125","documentation":"DigitalSigningAlgorithm.signer() throws IllegalStateException when asked for a signer but the JWK only carries public-key material (privateKey == null). Asymmetric signing requires the private key; a public JWK cannot produce signatures.","triggerScenarios":"Creating a signing algorithm from a JWK that contains only 'n'/'e' (RSA public) or only the public EC point, then calling signer(); using the verification key where the signing key was expected.","commonSituations":"Loading a JWKS document (which typically exposes only public keys) and trying to sign tokens with it; confusing the 'verify' key with the 'sign' key; JWK built from a certificate only.","solutions":["Provide a JWK containing the private key material (d for RSA/EC, k for oct keys)","Use verifier() instead of signer() when you only intend to verify signatures","Load the private key from your keystore/config into the JWK before creating the algorithm"],"exampleFix":"// before\nJWK pubJwk = JWK.load(publicKeyJson); alg.signer(); // fails\n// after\nJWK privJwk = JWK.load(privateKeyJson); // includes 'd' field\nalg = DigitalSigningAlgorithm.create(privJwk);\nSigner signer = alg.signer();","handlingStrategy":"validation","validationCode":"if (jwk.isPrivateKey() == false && needsSigning) throw new IllegalStateException(\"need private key JWK to sign\");","typeGuard":null,"tryCatchPattern":"try { signer = alg.signer(); } catch (IllegalStateException e) { // JWK is public-only: load signing key instead }","preventionTips":["Distinguish sign keys from verify keys at config load time (JWKS = public only)","Store the private key material for the issuer, public keys for verifiers","Assert key presence (JWK 'd' / 'k' fields) before building the signing pipeline"],"tags":["jwk","jwt","missing-key","illegal-state"],"backgroundTag":"missing-credentials","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}