apache/beam · error · java.lang.IllegalArgumentException
Schema in expansion request payload is not assignable to the
Error message
Schema in expansion request payload is not assignable to the schema for the configuration object.%n%nPayload Schema: %s%n%nConfiguration Schema: %s
What it means
Thrown by ExpansionService.payloadToConfig when the schema carried in an expansion request's payload Row is not assignable to the schema computed for the target configuration class. The service decodes the payload bytes into a Row and requires its schema to be compatible with configSchema before mapping the Row onto the configuration object via setters. This protects the service from populating a configuration object from structurally incompatible data.
Source
Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/ExpansionService.java:477
String.format(
"Failed to construct instance of configuration class '%s'",
configurationClass.getName()),
e);
}
}
}
private static <ConfigT> ConfigT payloadToConfigSchema(
ExternalConfigurationPayload payload, Class<ConfigT> configurationClass)
throws NoSuchSchemaException {
Schema configSchema = SCHEMA_REGISTRY.getSchema(configurationClass);
SerializableFunction<Row, ConfigT> fromRowFunc =
SCHEMA_REGISTRY.getFromRowFunction(configurationClass);
Row payloadRow = decodeConfigObjectRow(payload.getSchema(), payload.getPayload());
if (!payloadRow.getSchema().assignableTo(configSchema)) {
throw new IllegalArgumentException(
String.format(
"Schema in expansion request payload is not assignable to the schema for the "
+ "configuration object.%n%nPayload Schema: %s%n%nConfiguration Schema: %s",
payloadRow.getSchema(), configSchema));
}
return fromRowFunc.apply(payloadRow);
}
private static <ConfigT> ConfigT payloadToConfigSetters(
ExternalConfigurationPayload payload, Class<ConfigT> configurationClass)
throws ReflectiveOperationException {
Row configRow = decodeConfigObjectRow(payload.getSchema(), payload.getPayload());
Constructor<ConfigT> constructor = configurationClass.getDeclaredConstructor();
constructor.setAccessible(true);
ConfigT config = constructor.newInstance();View on GitHub (pinned to 12126d8942)
Solutions
- Upgrade the client SDK and the expansion service jar to the same Beam version so payload schemas match.
- Regenerate/rebuild the expansion request against the current transform's configuration class schema.
- Compare the 'Payload Schema' and 'Configuration Schema' printed in the message field-by-field to find the divergent field name/type and fix the payload construction code.
Example fix
// before: client built payload with old schema (field 'regex' as STRING vs new field 'pattern') // after: pin client and service to matching versions and rebuild the payload Row Row configRow = Row.withSchema(configSchema).addValues(pattern).build();
Defensive patterns
Strategy: validation
Validate before calling
Schema payloadSchema = Row.decode(...).getSchema(); // or payload.getSchema()
Schema configSchema = SCHEMA_REGISTRY.getSchema(MyConfig.class);
if (!payloadSchema.assignableTo(configSchema)) {
throw new IllegalStateException("Payload schema mismatch; sync client/server Beam versions");
} Type guard
boolean schemasCompatible(Row row, Schema config) { return row != null && row.getSchema() != null && row.getSchema().assignableTo(config); } Try / catch
try {
expansionResponse = service.expand(request);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("not assignable")) { /* rebuild payload with current schema */ }
else throw e;
} Prevention
- Pin client and expansion service to the same Beam version.
- Rebuild expansion requests whenever the transform's config class changes.
- Log and diff both schemas (message includes them) when upgrading.
When it happens
Trigger: Calling ExpansionService.expand (via the Beam expansion protocol) with a payload whose encoded Row schema differs from the schema derived from the configuration class — e.g. a client SDK of a different Beam version encoding fields with different names, types, or ordering than the server-side config class expects.
Common situations: Client and server Beam SDK version mismatch (schema evolution between releases); a custom transform whose config class changed after a client cached its expansion response; hand-crafted expansion requests built against an outdated schema.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to build transform from spec %s: %s
- Unable to generate coder for schema {schema}
- Expecting exactly one field, found
- The input schema must have exactly one field of type byte.
- Cannot merge schemas with different numbers of fields. schem
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8739971838efd4ec.
Report an issue: GitHub.