{"record":{"id":"6f9608e26220e0e6","repo":"jwtk/jjwt","slug":"specified-edwards-curve-publickey-does-not-match-t","errorCode":null,"errorMessage":"Specified Edwards Curve PublicKey does not match the specified PrivateKey's curve.","messagePattern":"Specified Edwards Curve PublicKey does not match the specified PrivateKey's curve\\.","errorType":"exception","errorClass":"InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/OctetPrivateJwkFactory.java","lineNumber":49,"sourceCode":"    public OctetPrivateJwkFactory() {\n        super(PrivateKey.class, DefaultOctetPrivateJwk.PARAMS);\n    }\n\n    @Override\n    protected boolean supportsKeyValues(JwkContext<?> ctx) {\n        return super.supportsKeyValues(ctx) && ctx.containsKey(DefaultOctetPrivateJwk.D.getId());\n    }\n\n    @Override\n    protected OctetPrivateJwk<PrivateKey, PublicKey> createJwkFromKey(JwkContext<PrivateKey> ctx) {\n        PrivateKey key = Assert.notNull(ctx.getKey(), \"PrivateKey cannot be null.\");\n        EdwardsCurve crv = EdwardsCurve.forKey(key);\n\n        PublicKey pub = ctx.getPublicKey();\n        if (pub != null) {\n            if (!crv.equals(EdwardsCurve.forKey(pub))) {\n                String msg = \"Specified Edwards Curve PublicKey does not match the specified PrivateKey's curve.\";\n                throw new InvalidKeyException(msg);\n            }\n        } else { // not supplied - try to generate it:\n            pub = EdwardsCurve.derivePublic(key);\n        }\n\n        // If a JWK fingerprint has been requested to be the JWK id, ensure we copy over the one computed for the\n        // public key per https://www.rfc-editor.org/rfc/rfc7638#section-3.2.1\n        boolean copyId = !Strings.hasText(ctx.getId()) && ctx.getIdThumbprintAlgorithm() != null;\n        JwkContext<PublicKey> pubCtx = OctetPublicJwkFactory.INSTANCE.newContext(ctx, pub);\n        OctetPublicJwk<PublicKey> pubJwk = OctetPublicJwkFactory.INSTANCE.createJwk(pubCtx);\n        ctx.putAll(pubJwk);\n        if (copyId) {\n            ctx.setId(pubJwk.getId());\n        }\n\n        //now add the d value\n        byte[] d = crv.getKeyMaterial(key);\n        Assert.notEmpty(d, \"Edwards PrivateKey 'd' value cannot be null or empty.\");","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/OctetPrivateJwkFactory.java#L31-L67","documentation":"When building an Octet (Edwards curve) private JWK from a private key, if a public key is also supplied it must live on the same Edwards curve as the private key. A curve mismatch throws InvalidKeyException; if no public key is supplied, JJWT derives it from the private key.","triggerScenarios":"Calling Jwts.SIG.Ed25519.keyPair() ... .toOctetPrivateJwk() (or OctetPrivateJwkFactory) while supplying a mismatched pair, e.g. an Ed25519 private key with an Ed448 public key (or vice versa) in the key context.","commonSituations":"Mixing keys from different keyPair() generations; loading keys from separate files/keystore entries that do not correspond; wrong key selected from a keystore alias.","solutions":["Ensure the public and private keys come from the same key pair / curve; omit the public key and let JJWT derive it from the private key.","Regenerate the pair with Jwts.SIG.Ed25519.keyPair().build() and use both members together.","Validate curves before calling: EdwardsCurve.forKey(priv).equals(EdwardsCurve.forKey(pub))."],"exampleFix":"// before\nbuilder.publicKey(pubFromOtherPair).privateKey(priv);\n// after\nKeyPair kp = Jwts.SIG.Ed25519.keyPair().build();\nbuilder.publicKey(kp.getPublic()).privateKey(kp.getPrivate());","handlingStrategy":"validation","validationCode":"if (pub != null && !EdwardsCurve.forKey(priv).equals(EdwardsCurve.forKey(pub))) {\n    throw new InvalidKeyException(\"Public/private curve mismatch\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    OctetPrivateJwk jwk = Jwts.SIG.Ed25519.keyPair()...toOctetPrivateJwk();\n} catch (InvalidKeyException e) {\n    // mismatched key pair\n}","preventionTips":["Always use both keys from the same KeyPair instance","Do not mix keys from different curves or generations","Let JJWT derive the public key when unsure"],"tags":["jwt","keys","jwk"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}