apache/seatunnel · error · RuntimeException

String json deserialization exception.<content>

Error message

String json deserialization exception.<content>

What it means

JsonUtils.parseObject(byte[]) parses raw bytes into a Jackson ObjectNode via readTree. On IOException it throws this RuntimeException whose message embeds the full offending content, helping identify bad payloads in logs.

Source

Thrown at seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/JsonUtils.java:275

     * @return json string
     */
    public static String toJsonString(Object object) {
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException("Object json deserialization exception.", e);
        }
    }

    public static ObjectNode parseObject(String text) {
        return parseObject(text.getBytes(StandardCharsets.UTF_8));
    }

    public static ObjectNode parseObject(byte[] content) {
        try {
            return (ObjectNode) OBJECT_MAPPER.readTree(content);
        } catch (IOException e) {
            throw new RuntimeException(
                    "String json deserialization exception."
                            + new String(content, StandardCharsets.UTF_8),
                    e);
        }
    }

    public static ArrayNode parseArray(String text) {
        try {
            return (ArrayNode) OBJECT_MAPPER.readTree(text);
        } catch (Exception e) {
            throw new RuntimeException("Json deserialization exception.", e);
        }
    }

    /** json serializer */
    public static class JsonDataSerializer extends JsonSerializer<String> {

        @Override

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Look at the content echoed in the exception message to spot HTML error pages, truncation or binary garbage
  2. Check upstream producers/senders — the payload itself is malformed, so fix at the source
  3. Guard for empty payloads before parsing (return early on null/empty)
  4. If responses can legitimately be non-JSON on failure, check the HTTP status/content-type before parsing

Example fix

// before
ObjectNode node = JsonUtils.parseObject(responseBody); // may be an HTML error page
// after
if (responseBody == null || responseBody.length == 0) { return null; }
ObjectNode node = JsonUtils.parseObject(responseBody);
Defensive patterns

Strategy: validation

Validate before calling

ObjectNode safeParse(byte[] content) {
    if (content == null || content.length == 0) return null;
    try { return JsonUtils.parseObject(content); }
    catch (RuntimeException e) { log.error("unparseable payload: {}", e.getMessage()); return null; }
}

Try / catch

try {
    ObjectNode node = JsonUtils.parseObject(bytes);
} catch (RuntimeException e) {
    // message contains the raw content — route to dead-letter/retry
    deadLetter.accept(bytes, e);
}

Prevention

When it happens

Trigger: Calling JsonUtils.parseObject(byte[] content) with bytes that are not valid JSON: empty arrays, binary data, truncated network reads, or non-UTF-8 encoded text.

Common situations: Parsing HTTP response bodies that contain error HTML, reading partially written files, deserializing messages from a queue where a producer wrote non-JSON data, charset mismatches after transport.

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/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/c6efef1496779f2c. Report an issue: GitHub.