apache/flink · error · RuntimeException

Could not serialize row '%s'.

Error message

Could not serialize row '%s'.

What it means

Thrown by CanalJsonSerializationSchema.serialize as a wrapper around any Throwable raised while encoding a RowData into Canal-JSON (it builds a reuse row with the data array and op type, then delegates to the JSON serializer). The cause identifies the real failure — typically the same field-level problems as RowDataToJsonConverters (1415... 1405/1406/1408/1409).

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/canal/CanalJsonSerializationSchema.java:89

                        ignoreNullFields);
    }

    @Override
    public void open(InitializationContext context) throws Exception {
        jsonSerializer.open(context);
        reuse = new GenericRowData(2);
    }

    @Override
    public byte[] serialize(RowData row) {
        try {
            StringData opType = rowKind2String(row.getRowKind());
            ArrayData arrayData = new GenericArrayData(new RowData[] {row});
            reuse.setField(0, arrayData);
            reuse.setField(1, opType);
            return jsonSerializer.serialize(reuse);
        } catch (Throwable t) {
            throw new RuntimeException("Could not serialize row '" + row + "'.", t);
        }
    }

    private StringData rowKind2String(RowKind rowKind) {
        switch (rowKind) {
            case INSERT:
            case UPDATE_AFTER:
                return OP_INSERT;
            case UPDATE_BEFORE:
            case DELETE:
                return OP_DELETE;
            default:
                throw new UnsupportedOperationException(
                        "Unsupported operation '" + rowKind + "' for row kind.");
        }
    }

    @Override

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Read the cause chain of the RuntimeException and fix the underlying converter error (see 1405/1406/1408/1409)
  2. Adjust sink table options ('json.map-null-key.mode'='DROP' or 'LITERAL') or schema (drop RAW columns)
  3. Round-trip test representative rows (nulls, nested maps, variants) through the canal-json serializer before deploying
  4. Quarantine failing records with a dead-letter sink instead of failing the whole job if data quality is the issue

Example fix

// before: sink schema contains RAW or maps with null keys and default options

// after
WITH ('connector'='kafka', 'format'='canal-json',
  'json.map-null-key.mode'='DROP')
-- and only JSON-compatible column types in the DDL
Defensive patterns

Strategy: try-catch

Validate before calling

// Smoke-test rows before sinking
try { serializer.serialize(sampleRow); } catch (RuntimeException e) { /* fix schema/options before deploy */ }

Try / catch

catch (RuntimeException e) — unwrap cause; fix the nested converter issue (map null keys, RAW type, variant); quarantine the record rather than failing the job if data-driven.

Prevention

When it happens

Trigger: Writing rows with format 'canal-json' to a sink where the inner JSON serialization throws: unsupported column type (RAW), map null keys in FAIL mode, malformed VARIANT values, or a value whose converter fails. Raised per record at runtime.

Common situations: Schema drift between the producing pipeline and the canal-json sink table; nullable keys from joins producing map null keys; exotic types in the sink schema; test rows not representative of production data.

Related errors


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