apache/beam · error · IllegalArgumentException
Unable to access MODEL$ field in SpecificRecordBase class
Error message
Unable to access MODEL$ field in SpecificRecordBase class
What it means
getGenericData(SpecificRecordBase) resolves the GenericData model associated with a generated Avro SpecificRecord. It first calls SpecificRecordBase.getSpecificData() (available since Avro 1.9); when that method is missing (NoSuchMethodError, Avro 1.8.2), it falls back to reflectively reading the static MODEL$ field. If reflection cannot access MODEL$ (the field was renamed, removed, or is not accessible), this IllegalArgumentException is thrown wrapping the IllegalAccessException.
Source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java:1778
*/
private static org.apache.avro.Schema buildHiveLogicalTypeSchema(
String hiveLogicalType, int size) {
String schemaJson =
String.format(
"{\"type\": \"string\", \"logicalType\": \"%s\", \"maxLength\": %s}",
hiveLogicalType, size);
return new org.apache.avro.Schema.Parser().parse(schemaJson);
}
static GenericData getGenericData(SpecificRecordBase record) {
try {
return record.getSpecificData();
} catch (NoSuchMethodError e) {
try {
// SpecificRecordBase.getSpecificData() was not available in avro 182
return (GenericData) FieldUtils.readStaticField(record.getClass(), "MODEL$", true);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException(
"Unable to access MODEL$ field in SpecificRecordBase class", ex);
}
}
}
private static <T> T checkRawType(
Class<T> desiredRawType,
Object value,
LogicalType logicalType,
Object rawType,
Conversion<?> conversion,
Class<?> convertedType) {
String msg =
String.format(
"Value %s of class %s is not a supported type for logical type %s (%s). "
+ "Underlying avro built-in raw type should be instance of %s. "
+ "However it is instance of %s and has value %s ."
+ "Generic data has conversion %s, convertedType %s",View on GitHub (pinned to 12126d8942)
Solutions
- Align Avro versions: ensure the generated SpecificRecord classes and the Beam pipeline use the same Avro version (>= 1.9 so getSpecificData() exists).
- Regenerate the SpecificRecord classes with the current avro-maven-plugin/avro-tools so MODEL$ and getSpecificData() are present and accessible.
- Check the classpath for duplicate/shaded Avro jars (mvn dependency:tree) and exclude the conflicting one.
Example fix
// before (pom.xml, mixed versions) <dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>1.8.2</version></dependency> // after <dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>1.11.3</version></dependency>
Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast at job setup
try {
GenericData gd = AvroUtils.getGenericData(sampleSpecificRecord);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Avro runtime version mismatch; align avro jars", e);
} Try / catch
try {
return AvroUtils.getGenericData(record);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("MODEL$")) {
throw new IllegalStateException(
"Generated class missing accessible MODEL$; regenerate with matching Avro version", e);
}
throw e;
} Prevention
- Pin a single Avro version across generated classes and Beam extensions (prefer >= 1.9).
- Run mvn dependency:tree to detect duplicate/ relocated avro jars.
- Regenerate SpecificRecords whenever the Avro version changes.
When it happens
Trigger: Using a generated Avro SpecificRecord class whose class hierarchy does not expose an accessible static MODEL$ field, while running with an Avro version where SpecificRecordBase.getSpecificData() is absent (e.g., 1.8.2) — the fallback FieldUtils.readStaticField(..., "MODEL$", true) then fails.
Common situations: Mixed Avro versions on the classpath (beam-sdks-java-extensions-avro compiled against one Avro version, generated classes compiled against another); generated classes from a custom codegen or a different Avro fork that omits MODEL$; shaded/relocated Avro where field names were obfuscated.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unable to find 'public static CoderProvider getCoderProvider
- Unable to invoke 'public static CoderProvider getCoderProvid
- Unable to generate coder for schema {schema}
- Unable to instantiate ExternalTransformBuilder from construc
- Failed to get the enclosing class of lambda
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/74f561879286ef3f.
Report an issue: GitHub.