apache/iceberg · error · JsonToMapException
parsing binary value threw exception for
Error message
parsing binary value threw exception for ${fieldName} What it means
extractBytes wraps the Jackson node binary decoding (`node.binaryValue()`) in a try/catch and rethrows any exception as JsonToMapException noting the field name. It means the JSON node could not be decoded as a Base64 binary value for a BYTES-typed field.
Solutions
- Ensure the JSON value for the field is valid Base64-encoded binary data.
- Base64-encode the bytes on the producing side before sending.
- Change the field's schema type to STRING if the data is actually textual.
Example fix
// before
{"payload": "not-valid-base64!!"}
// after
{"payload": "aGVsbG8="} Defensive patterns
Strategy: validation
Validate before calling
// Validate Base64 before producing/sending the record
try { java.util.Base64.getDecoder().decode(rawValue); } catch (IllegalArgumentException e) { /* fix payload upstream */ } Type guard
boolean isBase64(String s) { try { java.util.Base64.getDecoder().decode(s); return true; } catch (IllegalArgumentException e) { return false; } } Try / catch
try { ... } catch (org.apache.iceberg.connect.transforms.JsonToMapException e) { log.error("Bytes field invalid at " + e.getMessage(), e); /* route to DLQ */ } Prevention
- Always Base64-encode BYTES fields on the producing side
- Validate payloads with a JSON schema including base64 content encoding
- Watch for producers changing field encoding without versioning
When it happens
Trigger: extractValue routes a BYTES-typed field to extractBytes and the Jackson JsonNode is not valid Base64 binary data (e.g. an arbitrary string or malformed base64), causing node.binaryValue() to throw.
Common situations: JSON payloads where a bytes field contains a plain string or non-Base64-encoded data; producers changed encoding; hand-crafted test payloads with invalid Base64.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Expected json object for record.value after parsing
- record value is not a string, use StringConverter
- record.value is not valid json for record.value
- Unexpected type for field
- An error occurred closing catalog instance, ignoring...
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/cfff7e65b14e9f56.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-connect/kafka-connect-transforms/src/main/java/org/apache/iceberg/connect/transforms/JsonToMapUtils.java:276
default:
throw new JsonToMapException(
String.format("Unexpected type %s for field %s", type, fieldName));
}
return obj;
}
private static Object extractBytes(JsonNode node, String fieldName) {
Object obj;
try {
if (node.isBigInteger()) {
obj = new BigDecimal(node.bigIntegerValue());
} else if (node.isBigDecimal()) {
obj = node.decimalValue();
} else {
obj = node.binaryValue();
}
} catch (Exception e) {
throw new JsonToMapException(
String.format("parsing binary value threw exception for %s", fieldName), e);
}
return obj;
}
private static List<Object> populateArray(
JsonNode node, Schema schema, String fieldName, List<Object> acc) {
if (schema.type() == Schema.Type.ARRAY) {
node.elements()
.forEachRemaining(
arrayNode -> {
List<Object> nestedList = Lists.newArrayList();
acc.add(populateArray(arrayNode, schema.valueSchema(), fieldName, nestedList));
});
} else {
node.elements()
.forEachRemaining(
arrayEntry -> acc.add(extractValue(arrayEntry, schema.type(), fieldName)));View on GitHub (pinned to 86d9c8fc54)