{"record":{"id":"91df18740f8aafb6","repo":"jwtk/jjwt","slug":"byte-array-must-be-exactly-bitsmsg-this-bitlengt","errorCode":null,"errorMessage":"Byte array must be exactly ${bitsMsg(this.bitLength)}. Found ${bitsMsg(len)}","messagePattern":"Byte array must be exactly (.+?)\\. Found (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/lang/RequiredBitLengthConverter.java","lineNumber":41,"sourceCode":"\n    private final int bitLength;\n    private final boolean exact;\n\n    public RequiredBitLengthConverter(Converter<byte[], Object> converter, int bitLength) {\n        this(converter, bitLength, true);\n    }\n\n    public RequiredBitLengthConverter(Converter<byte[], Object> converter, int bitLength, boolean exact) {\n        this.converter = Assert.notNull(converter, \"Converter cannot be null.\");\n        this.bitLength = Assert.gt(bitLength, 0, \"bitLength must be greater than 0\");\n        this.exact = exact;\n    }\n\n    private byte[] assertLength(byte[] bytes) {\n        long len = Bytes.bitLength(bytes);\n        if (exact && len != this.bitLength) {\n            String msg = \"Byte array must be exactly \" + Bytes.bitsMsg(this.bitLength) + \". Found \" + Bytes.bitsMsg(len);\n            throw new IllegalArgumentException(msg);\n        } else if (len < this.bitLength) {\n            String msg = \"Byte array must be at least \" + Bytes.bitsMsg(this.bitLength) + \". Found \" + Bytes.bitsMsg(len);\n            throw new IllegalArgumentException(msg);\n        }\n        return bytes;\n    }\n\n    @Override\n    public Object applyTo(byte[] bytes) {\n        assertLength(bytes);\n        return this.converter.applyTo(bytes);\n    }\n\n    @Override\n    public byte[] applyFrom(Object o) {\n        byte[] result = this.converter.applyFrom(o);\n        return assertLength(result);\n    }","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/lang/RequiredBitLengthConverter.java#L23-L59","documentation":"RequiredBitLengthConverter.assertLength enforces that a byte array has an exact bit length when the converter was created with exact=true. If Bytes.bitLength(bytes) differs from the configured bitLength, this IllegalArgumentException reports the required and found sizes (via Bytes.bitsMsg).","triggerScenarios":"Providing a key/byte-array parameter (e.g. a 128-bit key claim) whose length in bits is not exactly the required amount, such as a 120-bit array where 128 bits is exact-required.","commonSituations":"Manually generated keys of the wrong size; keys trimmed or padded by other tooling; base64url-decoding inputs that lost bytes.","solutions":["Generate or resize the byte array to the exact required length (e.g. 16 bytes for 128 bits).","Use Keys.secretKeyFor(SignatureAlgorithm) or a proper key generator instead of hand-built arrays.","Verify with bytes.length * 8 == requiredBits before calling the API."],"exampleFix":"// before\nbyte[] key = new byte[15]; // 120 bits\n// after\nbyte[] key = new byte[16]; // exactly 128 bits","handlingStrategy":"validation","validationCode":"void requireExactBits(byte[] b, long bits) {\n    long len = b.length * 8L; // approximate; matches Bytes.bitLength semantics\n    if (len != bits) throw new IllegalArgumentException(\"Need exactly \" + bits + \" bits, got \" + len);\n}","typeGuard":null,"tryCatchPattern":"try {\n    converter.applyTo(bytes);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Byte array must be exactly\")) {\n        // regenerate/resize the byte array\n    }\n    throw e;\n}","preventionTips":["Generate keys with Keys.secretKeyFor() or SecureRandom of the right size","Assert byte-array length in bits before using cryptographic claims","Don't trim or pad key material manually"],"tags":["byte-array","key-length","validation"],"backgroundTag":"value-out-of-range","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"}