apache/flink · error · java.io.IOException

Failed to deserialize JSON '%s'.

Error message

Failed to deserialize JSON '%s'.

What it means

IOException thrown by JsonParserRowDataDeserializationSchema.deserialize(byte[], Collector) when parsing/conversion fails and ignoreParseErrors is false. The original Throwable is attached as the cause; the message embeds the raw payload. This is the standard 'bad JSON record fails the job' error for the streaming JSON parser schema.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonParserRowDataDeserializationSchema.java:100

            /* First: must point to a token; if not pointing to one, advance.
             * This occurs before first read from JsonParser, as well as
             * after clearing of current token.
             */
            if (root.currentToken() == null) {
                root.nextToken();
            }
            if (root.currentToken() != JsonToken.START_OBJECT
                    && root.currentToken() != JsonToken.START_ARRAY) {
                throw JsonMappingException.from(root, "No content to map due to end-of-input");
            }
            if (root.currentToken() == JsonToken.START_ARRAY) {
                processArray(root, out);
            } else {
                processObject(root, out);
            }
        } catch (Throwable t) {
            if (!ignoreParseErrors) {
                throw new IOException(
                        format("Failed to deserialize JSON '%s'.", new String(message)), t);
            }
            logParseErrorIfDebugEnabled(message, t);
        }
    }

    private void processArray(JsonParser root, Collector<RowData> out) throws IOException {
        while (root.nextToken() != JsonToken.END_ARRAY) {
            out.collect((RowData) runtimeConverter.convert(root));
        }
    }

    private void processObject(JsonParser root, Collector<RowData> out) throws IOException {
        out.collect((RowData) runtimeConverter.convert(root));
    }
}

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Inspect the embedded payload and the cause in the stack trace to see whether it is syntax or type mismatch
  2. Fix the producer/schema mismatch (correct column types in DDL to match real data)
  3. If dirty records are acceptable to drop, set 'json.ignore-parse-errors'='true' (then bad rows are skipped, and only logged in DEBUG)
  4. For truncation issues, verify the source's max message size / fetch settings

Example fix

-- before
'json.ignore-parse-errors' = 'false'

-- after (tolerate dirty records; note: they are silently dropped)
'json.ignore-parse-errors' = 'true'
Defensive patterns

Strategy: fallback

Validate before calling

// sample-validate before full ingestion (dev only):
try (JsonParser p = new JsonFactory().createParser(sampleBytes)) {
    p.nextToken(); // throws on truncated/non-JSON
}

Try / catch

catch (IOException e) {
    if (ignoreParseErrors) { /* row already skipped */ }
    else { log.error("bad record: {}", e.getMessage()); /* dead-letter it */ }
}

Prevention

When it happens

Trigger: Malformed JSON (truncated bytes, not an object/array at root, 'No content to map due to end-of-input'), or well-formed JSON whose values do not match the declared column types (string where int expected, out-of-range numbers), with 'json.ignore-parse-errors'='false' (default).

Common situations: Kafka messages split across records or binary garbage; upstream producers changing schemas without notice; charsets other than UTF-8; strict schemas hitting optional fields with wrong types.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/e7b359f2268b508b. Report an issue: GitHub.