{"record":{"id":"6c28f0dce7355669","repo":"jwtk/jjwt","slug":"strict-decoding-last-encoded-character-before-th","errorCode":null,"errorMessage":"Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. Expected the discarded bits from the character to be zero.","messagePattern":"Strict decoding: Last encoded character \\(before the paddings if any\\) is a valid base 64 alphabet but not a possible encoding\\. Expected the discarded bits from the character to be zero\\.","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/io/Base64Codec.java","lineNumber":774,"sourceCode":"    public boolean isUrlSafe() {\n        return this.encodeTable == URL_SAFE_ENCODE_TABLE;\n    }\n\n    /**\n     * Validates whether decoding the final trailing character is possible in the context\n     * of the set of possible base 64 values.\n     * <p>\n     * The character is valid if the lower bits within the provided mask are zero. This\n     * is used to test the final trailing base-64 digit is zero in the bits that will be discarded.\n     * </p>\n     *\n     * @param emptyBitsMask The mask of the lower bits that should be empty\n     * @param context       the context to be used\n     * @throws IllegalArgumentException if the bits being checked contain any non-zero value\n     */\n    private void validateCharacter(final int emptyBitsMask, final Context context) {\n        if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) {\n            throw new IllegalArgumentException(\n                    \"Strict decoding: Last encoded character (before the paddings if any) is a valid \" +\n                            \"base 64 alphabet but not a possible encoding. \" +\n                            \"Expected the discarded bits from the character to be zero.\");\n        }\n    }\n\n    /**\n     * Validates whether decoding allows an entire final trailing character that cannot be\n     * used for a complete byte.\n     *\n     * @throws IllegalArgumentException if strict decoding is enabled\n     */\n    private void validateTrailingCharacter() {\n        if (isStrictDecoding()) {\n            throw new IllegalArgumentException(\n                    \"Strict decoding: Last encoded character (before the paddings if any) is a valid \" +\n                            \"base 64 alphabet but not a possible encoding. \" +\n                            \"Decoding requires at least two trailing 6-bit characters to create bytes.\");","sourceCodeStart":756,"sourceCodeEnd":792,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/io/Base64Codec.java#L756-L792","documentation":"Error \"Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. Expected the discarded bits from the character to be zero.\" thrown in jwtk/jjwt.","triggerScenarios":"Thrown at impl/src/main/java/io/jsonwebtoken/impl/io/Base64Codec.java:774 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-encode the input with a standards-compliant Base64 encoder so the unused low bits of the final character are zero (strict/RFC 4648 canonical encoding)","Regenerate or re-fetch the token/data, since non-canonical padding bits usually indicate corruption or a non-conformant encoder","If lenient decoding of legacy data is required, decode without strict mode rather than altering the strict decoder"],"exampleFix":null,"handlingStrategy":"try-catch","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"}