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

  1. Re-encode the original bytes with standard Base64 (java.util.Base64.getEncoder() / `base64 -w0` on Linux to suppress wrapping).
  2. Verify length is a multiple of 4 and padding ('=') is present where required.
  3. Strip any embedded whitespace/newlines before embedding in JSON.
  4. 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

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


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/ad4e9846f3cb4c01.json. Report an issue: GitHub.