apache/iceberg · error · JsonToMapException
record.value is not valid json for record.value
Error message
record.value is not valid json for record.value: ${collectRecordDetails(record)} What it means
After confirming the value is a String, JsonToMapTransform parses it with Jackson readTree. If parsing fails (malformed JSON), it wraps the cause in JsonToMapException including record details ('record.value is not valid json for record.value: ...'). This means the value string is not syntactically valid JSON.
Solutions
- Fix the producer to emit valid JSON strings
- Validate sample messages from the topic (kafka-console-consumer) before configuring the sink
- Check for truncation (max.message.bytes / connector buffer limits) and encoding issues
- Route malformed messages to a dead-letter queue via errors.tolerance=all + errors.deadletterqueue.*
Example fix
// before (connector config, fail on bad data) "errors.tolerance": "none" // after (quarantine bad records for inspection) "errors.tolerance": "all", "errors.deadletterqueue.topic.name": "dlq-iceberg", "errors.deadletterqueue.context.headers.enable": "true"
Defensive patterns
Strategy: validation
Validate before calling
boolean isValidJson(String s) {
try { new ObjectMapper().readTree(s); return true; } catch (Exception e) { return false; }
} Try / catch
try {
return transform.apply(record);
} catch (JsonToMapException e) {
deadLetterQueue.send(record, e); // with errors.tolerance=all
return null;
} Prevention
- Fix producers to emit valid JSON
- Enable DLQ: errors.tolerance=all + errors.deadletterqueue.topic.name
- Sample topic data before configuring the Iceberg sink
- Check for truncation and encoding corruption in the transport
When it happens
Trigger: record.value() is a String but contains truncated output, non-JSON text (log lines, CSV), encoding corruption, or double-encoded/malformed JSON from the producer.
Common situations: Producers writing plain-text or CSV to a topic consumed by Iceberg sink; message size truncation; DMS emitting non-JSON payloads; charset/encoding mismatches corrupting bytes.
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
- Could not parse for
- Malformed JSON
- parsing binary value threw exception for
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/66803fb7c7028894.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-connect/kafka-connect-transforms/src/main/java/org/apache/iceberg/connect/transforms/JsonToMapTransform.java:82
if (record.value() == null) {
return record;
} else {
return process(record);
}
}
private R process(R record) {
if (!(record.value() instanceof String)) {
throw new JsonToMapException("record value is not a string, use StringConverter");
}
String json = (String) record.value();
JsonNode obj;
try {
obj = MAPPER.readTree(json);
} catch (Exception e) {
throw new JsonToMapException(
String.format(
"record.value is not valid json for record.value: %s", collectRecordDetails(record)),
e);
}
if (!(obj instanceof ObjectNode)) {
throw new JsonToMapException(
String.format(
"Expected json object for record.value after parsing: %s",
collectRecordDetails(record)));
}
if (startAtRoot) {
return singleField(record, (ObjectNode) obj);
}
return structRecord(record, (ObjectNode) obj);
}
View on GitHub (pinned to 86d9c8fc54)