apache/flink · error · IllegalArgumentException

Please use AvroParquetReaders.forSpecificRecord(Class<T>) fo

Error message

Please use AvroParquetReaders.forSpecificRecord(Class<T>) for SpecificRecord.

What it means

AvroParquetReaders.forReflectRecord(Class) refuses classes that extend SpecificRecordBase. Specific (generated) Avro classes must go through forSpecificRecord(Class) because their schema is available from the generated class itself, not via reflection-based POJO extraction.

Source

Thrown at flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/avro/AvroParquetReaders.java:72

                new AvroTypeInfo<>(typeClass), () -> SpecificData.get());
    }

    /**
     * Creates a new {@link AvroParquetRecordFormat} that reads the parquet file into Avro records
     * via reflection.
     *
     * <p>To read into Avro {@link GenericRecord GenericRecords}, use the {@link
     * #forGenericRecord(Schema)} method.
     *
     * <p>To read into Avro {@link org.apache.avro.specific.SpecificRecord SpecificRecords}, use the
     * {@link #forSpecificRecord(Class)} method.
     *
     * @see #forGenericRecord(Schema)
     * @see #forSpecificRecord(Class)
     */
    public static <T> StreamFormat<T> forReflectRecord(final Class<T> typeClass) {
        if (SpecificRecordBase.class.isAssignableFrom(typeClass)) {
            throw new IllegalArgumentException(
                    "Please use AvroParquetReaders.forSpecificRecord(Class<T>) for SpecificRecord.");
        } else if (GenericRecord.class.isAssignableFrom(typeClass)) {
            throw new IllegalArgumentException(
                    "Please use AvroParquetReaders.forGenericRecord(Class<T>) for GenericRecord."
                            + "Cannot read and create Avro GenericRecord without specifying the Avro Schema. "
                            + "This is because Flink needs to be able serialize the results in its data flow, which is"
                            + "very inefficient without the schema. And while the Schema is stored in the Avro file header,"
                            + "Flink needs this schema during 'pre-flight' time when the data flow is set up and wired,"
                            + "which is before there is access to the files");
        }

        // this is a PoJo that Avo will reader via reflect de-serialization
        // for Flink, this is just a plain PoJo type
        return new AvroParquetRecordFormat<>(
                TypeExtractor.createTypeInfo(typeClass), () -> ReflectData.get());
    }

    /**

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use AvroParquetReaders.forSpecificRecord(MyGeneratedRecord.class) for avro-generated classes
  2. Use AvroParquetReaders.forReflectRecord(MyPojo.class) only for plain POJOs without Avro base classes
  3. Use forGenericRecord(Schema) when you want schema-driven generic records

Example fix

// before
StreamFormat<MyRecord> f = AvroParquetReaders.forReflectRecord(MyRecord.class); // MyRecord extends SpecificRecordBase

// after
StreamFormat<MyRecord> f = AvroParquetReaders.forSpecificRecord(MyRecord.class);
Defensive patterns

Strategy: type-guard

Type guard

static <T> StreamFormat<T> avroFormat(Class<T> cls) {
  if (SpecificRecordBase.class.isAssignableFrom(cls)) return AvroParquetReaders.forSpecificRecord(cls.asSubclass(SpecificRecordBase.class).cast(null) == null ? cls : cls); // specific
  if (GenericRecord.class.isAssignableFrom(cls)) throw new IllegalArgumentException("need Schema");
  return AvroParquetReaders.forReflectRecord(cls);
}

Prevention

When it happens

Trigger: Calling AvroParquetReaders.forReflectRecord(MyGeneratedAvroRecord.class) where MyGeneratedAvroRecord extends org.apache.avro.specific.SpecificRecordBase (i.e., a class generated by avro-maven-plugin / avsc codegen).

Common situations: A codebase mixes hand-written POJOs and Avro-generated records; a developer passes the generated class to the generic reflection API by mistake, or an IDE auto-completes forReflectRecord.

Related errors


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