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
- Use the schema-taking factory: AvroCoder.of(GenericRecord.class, schemaString) or AvroCoder.of(GenericRecord.class, Schema)
- Use AvroCoder.of(Schema) / of(Class<T>, String schema) so the coder has a schema
- Define a SpecificRecord (avro-generated class) instead of GenericRecord so no schema argument is needed
- 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
- Never call AvroCoder.of(GenericRecord.class); always keep the schema string alongside GenericRecord pipelines
- Prefer SpecificRecord classes generated from your .avsc files
- Centralize coder creation in one factory so GenericRecord is special-cased once
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
- ApproximateUnique.PerKey requires its input to use KvCoder
- cannot encode a null BitSet
- cannot encode a null byte[]
- cannot encode a null Integer
- cannot encode a null Long
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)