apache/kafka · error · IllegalArgumentException
${about}: expected Base64-encoded binary data.
Error message
${about}: expected Base64-encoded binary data. What it means
Thrown by MessageUtil.jsonNodeToBinary when Jackson's node.binaryValue() returns null, meaning the node is not a JSON string containing Base64-encoded binary data. Kafka uses this reader for `bytes` protocol fields such as RawTaggedField payloads, transactional IDs, and certain opaque blobs that are serialized as Base64 text in JSON form.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java:169
} catch (NumberFormatException e) {
throw new NumberFormatException(about + ": failed to " +
"parse hexadecimal number: " + e.getMessage());
}
} else {
try {
return Long.parseLong(text);
} catch (NumberFormatException e) {
throw new NumberFormatException(about + ": failed to " +
"parse number: " + e.getMessage());
}
}
}
public static byte[] jsonNodeToBinary(JsonNode node, String about) {
try {
byte[] value = node.binaryValue();
if (value == null) {
throw new IllegalArgumentException(about + ": expected Base64-encoded binary data.");
}
return value;
} catch (IOException e) {
throw new UncheckedIOException(about + ": unable to retrieve Base64-encoded binary data", e);
}
}
public static double jsonNodeToDouble(JsonNode node, String about) {
if (!node.isFloatingPointNumber()) {
throw new NumberFormatException(about + ": expected a floating point " +
"type, but got " + node.getNodeType());
}
return node.asDouble();
}
public static byte[] duplicate(byte[] array) {
if (array == null)View on GitHub (pinned to c31c9215e1)
Solutions
- Encode the binary payload as Base64 (e.g. Base64.getEncoder().encodeToString(bytes) in Java or `base64` on the CLI) and put that string in the JSON.
- Confirm the node is a JSON string literal (quoted) — Jackson only decodes Base64 from TextNode.
- Verify the field actually expects bytes (check the message spec); if it expects a string, use the string accessor instead.
- If the field is optional and the value should be empty, pass an empty Base64 string "" rather than null.
Example fix
// before
{"transactional_id": "txn-42", "payload": "raw bytes here"}
// after
{"transactional_id": "txn-42", "payload": "cmF3IGJ5dGVzIGhlcmU="} Defensive patterns
Strategy: validation
Validate before calling
if (node == null || !node.isTextual()) throw new IllegalArgumentException("binary field must be a Base64 string");
byte[] b = java.util.Base64.getDecoder().decode(node.asText()); // throws on malformed Type guard
node != null && node.isTextual() && node.asText().matches("^[A-Za-z0-9+/]*={0,2}$") Try / catch
try { byte[] b = MessageUtil.jsonNodeToBinary(node, about); }
catch (IllegalArgumentException e) { /* not Base64 text; reject record */ } Prevention
- Always Base64-encode bytes (standard alphabet, with padding) before placing them in JSON.
- Do not put raw byte arrays, hex strings, or arrays of ints into binary fields.
- Use the same Base64 variant (standard vs URL-safe) on producer and consumer.
When it happens
Trigger: A JSON value for a `bytes` field is provided as a non-string node (number, object, array, boolean, null) or as a string that Jackson cannot interpret as Base64. node.binaryValue() returns null and line 169 throws IllegalArgumentException.
Common situations: Passing raw UTF-8 text where Base64 is expected (e.g. "hello" instead of "aGVsbG8="); passing null where bytes are required; sending a JSON object/array because the field name was reused; mis-rendering a byte[] from a Java dump that printed toString() rather than Base64.
Related errors
- ${about}: unable to retrieve Base64-encoded binary data
- ${about}: value ${value} does not fit in a 32-bit unsigned i
- ${about}: expected an integer or string type, but got ${node
- ${about}: failed to parse hexadecimal number: ${cause}
- ${about}: failed to parse number: ${cause}
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/fbd0849bc6e914c4.json.
Report an issue: GitHub.