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

  1. 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.
  2. Confirm the node is a JSON string literal (quoted) — Jackson only decodes Base64 from TextNode.
  3. Verify the field actually expects bytes (check the message spec); if it expects a string, use the string accessor instead.
  4. 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

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


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