apache/kafka · error · UncheckedIOException
${about}: unable to retrieve Base64-encoded binary data
Error message
${about}: unable to retrieve Base64-encoded binary data What it means
Thrown by MessageUtil.jsonNodeToBinary when node.binaryValue() throws IOException — i.e. the node IS a textual Base64 string but the content is malformed (illegal characters, wrong padding, or length not a multiple of 4). The original IOException is wrapped in an UncheckedIOException carrying this message.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java:174
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)
return null;
return Arrays.copyOf(array, array.length);
}
/**View on GitHub (pinned to c31c9215e1)
Solutions
- Re-encode the original bytes with standard Base64 (java.util.Base64.getEncoder() / `base64 -w0` on Linux to suppress wrapping).
- Verify length is a multiple of 4 and padding ('=') is present where required.
- Strip any embedded whitespace/newlines before embedding in JSON.
- If you produced the value with Base64.getUrlEncoder(), switch to Base64.getEncoder() (or vice versa) to match Jackson's default RFC 4648 §4 decoder.
Example fix
// before
{"payload": "aGVsbG8=d29ybGQ"} // missing padding, illegal mid-stream '='
// after
{"payload": "aGVsbG8=d29ybGQ="} // properly padded standard Base64 Defensive patterns
Strategy: try-catch
Validate before calling
if (node != null && node.isTextual()) {
try { java.util.Base64.getDecoder().decode(node.asText()); }
catch (IllegalArgumentException ex) { throw new IllegalArgumentException("invalid Base64", ex); }
} else { throw new IllegalArgumentException("binary field missing"); } Type guard
node != null && node.isTextual() && java.util.Base64.getDecoder().decode(node.asText()) != null
Try / catch
try { byte[] b = MessageUtil.jsonNodeToBinary(node, about); }
catch (java.io.UncheckedIOException e) { /* malformed/undecodable Base64 payload; drop or DLQ */ } Prevention
- Pre-decode-test Base64 strings at ingest to catch truncation/padding errors early.
- Validate Base64 length is a multiple of 4 (with padding).
- Catch UncheckedIOException distinctly from IllegalArgumentException so IO failures are visible in logs.
When it happens
Trigger: A JSON string value for a `bytes` field is recognized as Base64 by Jackson but fails strict Base64 decoding: characters outside the Base64 alphabet, missing '=' padding, truncated segments, or embedded whitespace/newlines that the strict decoder rejects.
Common situations: Hand-editing a Base64 string and dropping a character; copy-paste that stripped trailing '=' padding; base64 output that includes URL-safe characters ('-'/'_') where standard ('+'/'/') is expected; line-wrapped PEM-style Base64 pasted as a single JSON string with newlines; encoding that used a different alphabet (RFC 4648 §5 vs §4).
Related errors
- ${about}: expected Base64-encoded binary data.
- ${about}: failed to parse hexadecimal number: ${cause}
- ${about}: failed to parse number: ${cause}
- ${about}: value ${value} does not fit in a 32-bit unsigned i
- ${about}: expected an integer or string type, but got ${node
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/ad4e9846f3cb4c01.json.
Report an issue: GitHub.