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

  1. Fix the producer to emit valid JSON strings
  2. Validate sample messages from the topic (kafka-console-consumer) before configuring the sink
  3. Check for truncation (max.message.bytes / connector buffer limits) and encoding issues
  4. 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

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


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)