apache/flink · error · UnsupportedOperationException

Unsupported operation '%s' for row kind.

Error message

Unsupported operation '%s' for row kind.

What it means

MaxwellJsonSerializationSchema.rowKind2String maps only INSERT/UPDATE_AFTER to 'insert' and UPDATE_BEFORE/DELETE to 'delete'. Any other RowKind reaches the default branch and throws UnsupportedOperationException — in practice unreachable with the standard four CDC kinds, but hit if a custom operator emits an extended RowKind.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/maxwell/MaxwellJsonSerializationSchema.java:94

    }

    @Override
    public byte[] serialize(RowData element) {
        reuse.setField(0, element);
        reuse.setField(1, rowKind2String(element.getRowKind()));
        return jsonSerializer.serialize(reuse);
    }

    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
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        MaxwellJsonSerializationSchema that = (MaxwellJsonSerializationSchema) o;
        return Objects.equals(jsonSerializer, that.jsonSerializer)
                && timestampFormat == that.timestampFormat;
    }

    @Override

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Clamp non-CDC RowKinds to INSERT (or UPDATE_AFTER) in a map before the sink.
  2. Audit custom operators for RowKind.fromShortValue/valueOf usage and restrict to the four CDC kinds.

Example fix

// before
row.setRowKind(RowKind.fromShortValue((short) 9));
// after
row.setRowKind(RowKind.INSERT);
Defensive patterns

Strategy: type-guard

Type guard

static String maxwellOpOf(RowKind k) {
    switch (k) {
        case INSERT:
        case UPDATE_AFTER: return "insert";
        case UPDATE_BEFORE:
        case DELETE: return "delete";
        default: return null; // caller clamps or rejects before serialization
    }
}

Prevention

When it happens

Trigger: A custom source/function upstream of a maxwell-json sink sets a RowKind outside the four standard values; test code constructs RowData with RowKind.valueOf on an unknown identifier.

Common situations: Reusing RowKind short codes for custom markers; evolving Flink versions adding RowKind values not covered by the format; unit tests feeding arbitrary kinds.

Related errors


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