apache/flink · error · IllegalArgumentException

Field at index must be of type byte[], but was

Error message

Field at index %s must be of type byte[], but was %s

What it means

Thrown by RowFieldExtractorSchema.serialize when the Row field at the configured index exists but is not a byte[]. This schema is designed solely to extract a raw byte[] field (e.g. a pre-serialized Kafka key or value), so any other type is a programming error. The message reports the actual field type so the developer can correct the Row schema or the extractor index.

Solutions

  1. Ensure the Row field at the configured index is actually byte[] (BINARY/VARBINARY in the Table schema).
  2. If the field is a String or other type, convert it to byte[] before it enters the Row, or use a different SerializationSchema (e.g. a JSON or string schema).
  3. Verify the fieldIndex argument matches the intended binary column; reorder the Row or change the index.

Example fix

// before: Row has a String at index 1
Row.of(123L, "hello");
new RowFieldExtractorSchema(1); // throws: field is String not byte[]

// after: store bytes at index 1
Row.of(123L, "hello".getBytes(StandardCharsets.UTF_8));
new RowFieldExtractorSchema(1);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the Row field type before serializing
Object field = row.getField(index);
if (field != null && !(field instanceof byte[])) {
    throw new IllegalStateException(
        "Row field at index " + index + " is " + field.getClass().getName()
        + " — convert to byte[] before using RowFieldExtractorSchema.");
}

Type guard

public static boolean isByteField(Row row, int index) {
    Object field = row.getField(index);
    return field == null || field instanceof byte[];
}

Try / catch

try {
    byte[] out = extractor.serialize(row);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Field at index")) {
        // route to error handling / side output
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling serialize() on a Row where the field at fieldIndex is a String, Integer, or any non-byte[] type. This happens when the upstream Row schema was defined with a non-VARBINARY/BINARY field but the RowFieldExtractorSchema was configured to read that index.

Common situations: Mismatch between the Table/Row schema field types and the configured KafkaRecordSerializationSchema key/value extractor; changing a field type from BYTES to STRING without updating the extractor; indexing the wrong field that happens to be a non-binary column.

Related errors


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

Appendix: source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/serialization/RowFieldExtractorSchema.java:97

    @Override
    public byte[] serialize(@Nullable Row element) {
        if (element == null) {
            return new byte[0];
        }

        checkArgument(
                fieldIndex < element.getArity(),
                "Cannot access field %s in Row with arity %s",
                fieldIndex,
                element.getArity());

        Object field = element.getField(fieldIndex);
        if (field == null) {
            return new byte[0];
        }

        if (!(field instanceof byte[])) {
            throw new IllegalArgumentException(
                    String.format(
                            "Field at index %s must be of type byte[], but was %s",
                            fieldIndex, field.getClass().getName()));
        }

        return (byte[]) field;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RowFieldExtractorSchema that = (RowFieldExtractorSchema) o;
        return fieldIndex == that.fieldIndex;

View on GitHub (pinned to 2f3c205e92)