{"record":{"id":"ffea2cc0e2c2e66f","repo":"jwtk/jjwt","slug":"b64-unencoded-payload-option-has-been-specified","errorCode":null,"errorMessage":"'b64' Unencoded payload option has been specified, but payload is empty.","messagePattern":"'b64' Unencoded payload option has been specified, but payload is empty\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java","lineNumber":619,"sourceCode":"\n        byte[] signature;\n        try {\n            SecureRequest<InputStream, Key> request = new DefaultSecureRequest<>(signingInput, provider, secureRandom, key);\n            signature = signFunction.apply(request);\n\n            // now that we've calculated the signature, if using the b64 extension, and the payload is\n            // attached ('non-detached'), we need to include it in the jws before the signature token.\n            // (Note that if encodePayload is true, the payload has already been written to jws at this point, so\n            // we only need to write if encodePayload is false and the payload is attached):\n            if (!this.encodePayload) {\n                if (!payload.isCompressed() // don't print raw compressed bytes\n                        && (payload.isClaims() || payload.isString())) {\n                    // now add the payload to the jws output:\n                    Streams.copy(payloadStream, jws, new byte[8192], \"Unable to copy attached Payload InputStream.\");\n                }\n                if (payloadStream instanceof CountingInputStream && ((CountingInputStream) payloadStream).getCount() <= 0) {\n                    String msg = \"'b64' Unencoded payload option has been specified, but payload is empty.\";\n                    throw new IllegalStateException(msg);\n                }\n            }\n        } finally {\n            Streams.reset(payloadStream);\n        }\n\n        // ----- separator -----\n        jws.write(DefaultJwtParser.SEPARATOR_CHAR);\n\n        // ----- signature -----\n        encodeAndWrite(\"JWS Signature\", signature, jws);\n\n        return Strings.utf8(jws.toByteArray());\n    }\n\n    private String unprotected(final Payload content) {\n\n        Assert.stateNotNull(content, \"Content argument cannot be null.\");","sourceCodeStart":601,"sourceCodeEnd":637,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java#L601-L637","documentation":"Thrown from sign() (invoked by compact()) when the 'b64':false unencoded-payload JWS option is set but the payload produces zero bytes. With unencoded payloads the signature must be computed over the raw payload, so an empty payload makes the detached/unencoded construction impossible and the builder fails with an IllegalStateException.","triggerScenarios":"Calling b64(false) (unencoded payload option) on a JwtBuilder while the payload is empty — i.e. no content/claims set, or content that serializes to zero bytes — then compact().","commonSituations":"Detached-content JWS flows where the caller forgot to attach the payload before compacting; conditional code paths that skip setContent(); misuse of b64(false) copied from unencoded-payload examples.","solutions":["Ensure setContent(...) or setClaims(...) provides a non-empty payload before compact()","Remove the b64(false) call if you do not actually need unencoded (detached) payloads","Validate that the content InputStream/byte[] is non-empty before building"],"exampleFix":"// before\nString jws = Jwts.builder().b64(false).compact(); // payload never set\n// after\nString jws = Jwts.builder().b64(false).setContent(payloadBytes).compact();","handlingStrategy":"validation","validationCode":"if (unencodedPayload && (content == null || content.length == 0)) {\n    throw new IllegalArgumentException(\"Unencoded-payload JWS requires non-empty content\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return builder.compact();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"payload is empty\")) {\n        throw new TokenBuildException(\"b64:false requires non-empty payload\", e);\n    }\n    throw e;\n}","preventionTips":["Only call b64(false) when you truly need detached/unencoded payloads","Assert content is non-empty before compact()","Set content immediately after b64(false) so it cannot be skipped by a code path"],"tags":["jwt","jws","empty-payload"],"backgroundTag":"empty-required-field","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"}