{"record":{"id":"065838b152330d30","repo":"jwtk/jjwt","slug":"unable-to-derive-ecpublickey-from-ecprivatekey","errorCode":null,"errorMessage":"Unable to derive ECPublicKey from ECPrivateKey: ${e.getMessage()}","messagePattern":"Unable to derive ECPublicKey from ECPrivateKey: (.+?)","errorType":"exception","errorClass":"io.jsonwebtoken.security.InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/EcPrivateJwkFactory.java","lineNumber":67,"sourceCode":"        return super.supportsKeyValues(ctx) && ctx.containsKey(DefaultEcPrivateJwk.D.getId());\n    }\n\n    // visible for testing\n    protected ECPublicKey derivePublic(KeyFactory keyFactory, ECPublicKeySpec spec) throws InvalidKeySpecException {\n        return (ECPublicKey) keyFactory.generatePublic(spec);\n    }\n\n    protected ECPublicKey derivePublic(final JwkContext<ECPrivateKey> ctx) {\n        final ECPrivateKey key = ctx.getKey();\n        return generateKey(ctx, ECPublicKey.class, new CheckedFunction<KeyFactory, ECPublicKey>() {\n            @Override\n            public ECPublicKey apply(KeyFactory kf) {\n                try {\n                    ECPublicKeySpec spec = ECCurve.publicKeySpec(key);\n                    return derivePublic(kf, spec);\n                } catch (Exception e) {\n                    String msg = \"Unable to derive ECPublicKey from ECPrivateKey: \" + e.getMessage();\n                    throw new InvalidKeyException(msg, e);\n                }\n            }\n        });\n    }\n\n    @Override\n    protected EcPrivateJwk createJwkFromKey(JwkContext<ECPrivateKey> ctx) {\n\n        ECPrivateKey key = ctx.getKey();\n        ECPublicKey ecPublicKey;\n\n        PublicKey publicKey = ctx.getPublicKey();\n        if (publicKey != null) {\n            ecPublicKey = Assert.isInstanceOf(ECPublicKey.class, publicKey, ECPUBKEY_ERR_MSG);\n        } else {\n            ecPublicKey = derivePublic(ctx);\n        }\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/EcPrivateJwkFactory.java#L49-L85","documentation":"When creating an EC public JWK from an ECPrivateKey, EcPrivateJwkFactory derives the matching ECPublicKey from the private key's parameters. If KeyFactory fails to derive the public key (bad or missing EC parameters, provider issues), the underlying exception message is wrapped in this InvalidKeyException.","triggerScenarios":"Building a JWK from an ECPrivateKey whose parameters are incomplete or unsupported, e.g. a private key with null params that cannot resolve the curve, or a provider whose KeyFactory cannot build the ECPublicKeySpec.","commonSituations":"HSM/PKCS11 EC private keys that refuse to expose public parameters; custom security providers; keys deserialized or constructed without ECParameterSpec.","solutions":["Use an ECPrivateKey created with ECGenParameterSpec (e.g. secp256r1) so public-key parameters are available.","Regenerate or re-import the key with a standard provider (SunEC) if the current provider cannot derive the public key.","Read the wrapped cause (e.getCause().getMessage()) to identify the actual KeyFactory failure.","If the key comes from an HSM, build the JWK from values (x, y, d, crv) instead of from the Key object."],"exampleFix":"// before\nKeyPairGenerator kg = KeyPairGenerator.getInstance(\"EC\"); // no named curve spec\nkg.initialize(new ECGenParameterSpec(\"secp256r1\")); // omitted in failing code path\n// after\nKeyPairGenerator kg = KeyPairGenerator.getInstance(\"EC\");\nkg.initialize(new ECGenParameterSpec(\"secp256r1\"));\nKeyPair kp = kg.generateKeyPair();\nJwk jwk = Jwks.builder().setKey(kp.getPrivate()).build();","handlingStrategy":"try-catch","validationCode":"if (key instanceof ECKey && ((ECKey) key).getParams() == null) {\n    throw new IllegalArgumentException(\"ECPrivateKey is missing curve parameters; regenerate with a named curve\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Jwk<?> jwk = Jwks.builder().setKey(ecPrivateKey).build();\n} catch (io.jsonwebtoken.security.InvalidKeyException e) {\n    // inspect e.getCause() for the KeyFactory failure; build JWK from values instead\n}","preventionTips":["Generate EC keys with ECGenParameterSpec so public parameters exist","For HSM keys, create JWKs from explicit x/y/d/crv values rather than the Key object"],"tags":["java","jjwt","ec","jwk","key-derivation"],"backgroundTag":"invalid-key-algorithm","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}