apache/beam · error · IllegalArgumentException

AvroCoder for GenericRecord requires a schema

Error message

AvroCoder for GenericRecord requires a schema

What it means

AvroCoder.of(Class) refuses to create a coder for raw GenericRecord.class because a GenericRecord carries no embedded schema; a schema must be supplied explicitly. Calling the class-only factory with GenericRecord is therefore an invalid use and throws IllegalArgumentException.

Solutions

  1. Use the schema-taking factory: AvroCoder.of(GenericRecord.class, schemaString) or AvroCoder.of(GenericRecord.class, Schema)
  2. Use AvroCoder.of(Schema) / of(Class<T>, String schema) so the coder has a schema
  3. Define a SpecificRecord (avro-generated class) instead of GenericRecord so no schema argument is needed
  4. Check the pipeline for a generic .setCoder(AvroCoder.of(type)) call and special-case GenericRecord

Example fix

// before
AvroCoder.of(GenericRecord.class) // throws
// after
AvroCoder.of(GenericRecord.class, schemaString)
Defensive patterns

Strategy: validation

Validate before calling

if (GenericRecord.class.equals(type) && schemaString == null) {
  throw new IllegalArgumentException("Provide an Avro schema when coding GenericRecord");
}

Type guard

boolean canCreateClassOnlyAvroCoder(Class<?> type) {
  return !GenericRecord.class.equals(type);
}

Try / catch

try {
  coder = AvroCoder.of(type);
} catch (IllegalArgumentException e) {
  coder = AvroCoder.of(GenericRecord.class, schemaString);
}

Prevention

When it happens

Trigger: Calling AvroCoder.of(GenericRecord.class) (optionally with useReflectApi) without going through the schema-taking overload AvroCoder.of(GenericRecord.class, schemaJsonString) or AvroCoder.of(schema).

Common situations: Generic pipelines that pass Class objects generically and forget GenericRecord is special; coders inferred from a PCollection element type after a transform widened it to GenericRecord; copying sample code that used SpecificRecord and switching to GenericRecord.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c90540fb586c8ed7. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/coders/AvroCoder.java:233

  /**
   * Returns an {@code AvroCoder} instance for the provided element class.
   *
   * @param <T> the element type
   */
  public static <T> AvroCoder<T> of(Class<T> clazz) {
    return of(clazz, true);
  }

  /**
   * Returns an {@code AvroCoder} instance for the given class, respecting whether to use Avro's
   * Reflect* or Specific* suite for encoding and decoding.
   *
   * @param <T> the element type
   */
  public static <T> AvroCoder<T> of(Class<T> type, boolean useReflectApi) {
    if (GenericRecord.class.equals(type)) {
      throw new IllegalArgumentException("AvroCoder for GenericRecord requires a schema");
    } else if (SpecificRecord.class.isAssignableFrom(type) && !useReflectApi) {
      return specific(type);
    } else {
      return reflect(type);
    }
  }

  /**
   * Returns an {@code AvroCoder} instance for the provided element type using the provided Avro
   * schema
   *
   * <p>The schema must correspond to the type provided.
   *
   * @param <T> the element type
   */
  public static <T> AvroCoder<T> of(Class<T> type, Schema schema) {
    return of(type, schema, true);
  }

View on GitHub (pinned to 12126d8942)