{"record":{"id":"10c29e303fac3ee1","repo":"jwtk/jjwt","slug":"missing-required-encoded-bytes-for-key-tostring","errorCode":null,"errorMessage":"Missing required encoded bytes for key [${toString(key)}].","messagePattern":"Missing required encoded bytes for key \\[(.+?)\\]\\.","errorType":"exception","errorClass":"InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/KeysBridge.java","lineNumber":155,"sourceCode":"            if (curve != null) bitlen = curve.getKeyBitLength();\n        }\n\n        return bitlen;\n    }\n\n    public static byte[] getEncoded(Key key) {\n        Assert.notNull(key, \"Key cannot be null.\");\n        byte[] encoded;\n        try {\n            encoded = key.getEncoded();\n        } catch (Throwable t) {\n            String msg = \"Cannot obtain required encoded bytes from key [\" + KeysBridge.toString(key) + \"]: \" +\n                    t.getMessage();\n            throw new InvalidKeyException(msg, t);\n        }\n        if (Bytes.isEmpty(encoded)) {\n            String msg = \"Missing required encoded bytes for key [\" + toString(key) + \"].\";\n            throw new InvalidKeyException(msg);\n        }\n        return encoded;\n    }\n\n    public static String toString(Key key) {\n        if (key == null) {\n            return \"null\";\n        }\n        if (key instanceof PublicKey) {\n            return key.toString(); // safe to show internal key state as it's a public key\n        }\n        // else secret or private key, don't show internal key state, just public attributes\n        return \"class: \" + key.getClass().getName() +\n                \", algorithm: \" + key.getAlgorithm() +\n                \", format: \" + key.getFormat();\n    }\n}\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/KeysBridge.java#L137-L173","documentation":"KeysBridge.getEncoded throws InvalidKeyException with this message when key.getEncoded() succeeds but returns null or an empty array. jjwt needs actual key bytes for normalization/signing; a key with no encoded form (or one whose encoding the provider withholds) cannot be used.","triggerScenarios":"Calling jjwt APIs that require encoded key bytes with a key whose getEncoded() returns null/empty — e.g. platform keys that deliberately expose no encoding (some Android Keystore, PKCS11 tokens returning null), or a custom Key implementation returning null.","commonSituations":"Android Keystore secret keys in newer API levels returning null from getEncoded(); custom Key wrappers in tests; keys reconstructed without their encoding (e.g. RSAPrivateKeySpec variants lacking CRT data normalized away).","solutions":["Use a key that exposes its encoding: generate with KeyGenerator/SecretKeySpec, or keep the original bytes you constructed the key from.","On Android, store raw key material outside Keystore for jjwt use, or derive a software key.","For custom Key implementations, implement getEncoded() to return real bytes.","If the bytes came from a keystore, reload via the original SecretKeySpec/KeyFactory rather than relying on getEncoded()."],"exampleFix":"// before\nSecretKey key = keystoreSecretKeyWithNullEncoding();\nJwts.parser().verifyWith(key); // InvalidKeyException: missing encoded bytes\n\n// after\nSecretKey key = new SecretKeySpec(rawBytes, \"HmacSHA256\");\nJwts.parser().verifyWith(key); // has encoded bytes","handlingStrategy":"validation","validationCode":"boolean hasEncodedForm(Key key) {\n    try { byte[] enc = key.getEncoded(); return enc != null && enc.length > 0; }\n    catch (Throwable t) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.verifyWith(key);\n} catch (InvalidKeyException e) {\n    if (e.getMessage().startsWith(\"Missing required encoded bytes\")) {\n        // reconstruct with new SecretKeySpec(originalBytes, alg)\n    } else throw e;\n}","preventionTips":["Keep the original key bytes and rebuild keys via SecretKeySpec instead of relying on keystore getEncoded().","On Android, avoid non-exported Keystore keys for jjwt operations.","For custom Key implementations, always return real bytes from getEncoded()."],"tags":["key","encoded-bytes","invalidkey","empty-bytes","jsonwebtoken"],"backgroundTag":"invalid-key-material","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"}