apache/flink · error · RuntimeException

Row arity of from ({}) does not match this serializer's fiel

Error message

Row arity of from ({}) does not match this serializer's field length ({}).

What it means

RowSerializer.copyPositionBased() copies a position-based Row (one without named fields). Before copying each field, it asserts that the source Row's arity equals the serializer's configured field count (fieldSerializers.length). If they differ, this RuntimeException is thrown with both numbers in the message. The serializer can only copy Rows whose arity exactly matches its schema.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/RowSerializer.java:148

    public Row createInstance() {
        return RowUtils.createRowWithNamedPositions(
                RowKind.INSERT, new Object[fieldSerializers.length], positionByName);
    }

    @Override
    public Row copy(Row from) {
        final Set<String> fieldNames = from.getFieldNames(false);
        if (fieldNames == null) {
            return copyPositionBased(from);
        } else {
            return copyNameBased(from, fieldNames);
        }
    }

    private Row copyPositionBased(Row from) {
        final int length = fieldSerializers.length;
        if (from.getArity() != length) {
            throw new RuntimeException(
                    "Row arity of from ("
                            + from.getArity()
                            + ") does not match "
                            + "this serializer's field length ("
                            + length
                            + ").");
        }
        final Object[] fieldByPosition = new Object[length];
        for (int i = 0; i < length; i++) {
            final Object fromField = from.getField(i);
            if (fromField != null) {
                final Object copy = fieldSerializers[i].copy(fromField);
                fieldByPosition[i] = copy;
            }
        }
        return RowUtils.createRowWithNamedPositions(
                from.getKind(), fieldByPosition, positionByName);
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure every Row passed to the serializer has arity == the serializer's fieldSerializers.length.
  2. If the schema changed, update all downstream operators and serializers to the new arity.
  3. If restoring from a savepoint with a different arity, implement state migration or start fresh.
  4. Validate Row arity in an upstream MapFunction before it reaches the serializer.

Example fix

// before — Row arity 3 fed to a serializer expecting arity 2
RowSerializer ser = new RowSerializer(new TypeSerializer[]{intSer, strSer}); // length 2
ser.copy(Row.of(1, "a", 42)); // arity 3 ≠ 2 → exception

// after — match arity
RowSerializer ser = new RowSerializer(new TypeSerializer[]{intSer, strSer, intSer}); // length 3
ser.copy(Row.of(1, "a", 42)); // arity 3 == 3 → OK
Defensive patterns

Strategy: validation

Validate before calling

// Validate Row arity before copying
public static Row safeCopy(RowSerializer ser, Row from) {
    if (from.getArity() != ser.getArity()) {
        throw new IllegalArgumentException(
            "Row arity " + from.getArity()
            + " != serializer arity " + ser.getArity());
    }
    return ser.copy(from);
}

Try / catch

try {
    Row copy = serializer.copy(from);
} catch (RuntimeException e) {
    if (e.getMessage().contains("Row arity of from")) {
        log.error("Arity mismatch: expected {}, got {}",
            serializer.getArity(), from.getArity());
    }
    throw e;
}

Prevention

When it happens

Trigger: RowSerializer.copy(Row) is called (e.g., during state snapshot, shuffle, or operator chaining) with a Row whose getArity() does not equal the number of field serializers the RowSerializer was constructed with.

Common situations: The upstream operator emits a Row with a different number of fields than the TypeInformation/RowSerializer expects; a schema change (adding/removing a column) was made to one operator but not downstream; restoring state from a savepoint whose Row schema has a different arity; a union of two streams with different Row arities feeding into the same operator.

Related errors


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