{"record":{"id":"61465878e76cd089","repo":"jwtk/jjwt","slug":"familyname-signing-keys-must-be-privatekey-inst","errorCode":null,"errorMessage":"${familyName} signing keys must be PrivateKey instances.","messagePattern":"(.+?) signing keys must be PrivateKey instances\\.","errorType":"exception","errorClass":"InvalidKeyException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java","lineNumber":406,"sourceCode":"                            \"size >= \" + minKeyLength + \" bits (the key size must be greater than or equal to the hash \" +\n                            \"output size).  Consider using the \" + Keys.class.getName() + \" class's \" +\n                            \"'secretKeyFor(SignatureAlgorithm.\" + name() + \")' method to create a key guaranteed to be \" +\n                            \"secure enough for \" + name() + \".  See \" +\n                            \"https://tools.ietf.org/html/rfc7518#section-3.2 for more information.\";\n                    throw new WeakKeyException(msg);\n                }\n            } finally {\n                if (encoded != null) {\n                    Arrays.fill(encoded, (byte) 0);\n                }\n            }\n\n        } else { //EC or RSA\n\n            if (signing) {\n                if (!(key instanceof PrivateKey)) {\n                    String msg = familyName + \" signing keys must be PrivateKey instances.\";\n                    throw new InvalidKeyException(msg);\n                }\n            }\n\n            if (isEllipticCurve()) {\n\n                if (!(key instanceof ECKey)) {\n                    String msg = familyName + \" \" + keyType(signing) + \" keys must be ECKey instances.\";\n                    throw new InvalidKeyException(msg);\n                }\n\n                ECKey ecKey = (ECKey) key;\n                int size = ecKey.getParams().getOrder().bitLength();\n                if (size < this.minKeyLength) {\n                    String msg = \"The \" + keyType(signing) + \" key's size (ECParameterSpec order) is \" + size +\n                            \" bits which is not secure enough for the \" + name() + \" algorithm.  The JWT \" +\n                            \"JWA Specification (RFC 7518, Section 3.4) states that keys used with \" +\n                            name() + \" MUST have a size >= \" + this.minKeyLength +\n                            \" bits.  Consider using the \" + Keys.class.getName() + \" class's \" +","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java#L388-L424","documentation":"Type guard in SignatureAlgorithm.assertValid for the asymmetric branch (EC or RSA): when signing, the key must be a java.security.PrivateKey, since signing requires private-key material. A PublicKey, SecretKey, or other Key subtype supplied for signing with an ES*/RS*/PS* algorithm triggers InvalidKeyException.","triggerScenarios":"Thrown at api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java:406 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass the PrivateKey from a KeyPair for signing; obtain one via Keys.keyPairFor(SignatureAlgorithm.RS256/ES256 etc.).","If only a public key is available, the operation should be signature verification, not signing — use assertValidVerificationKey or the parser side.","Load the private key from a keystore/PKCS8 file rather than reusing a certificate's public key."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}