apache/beam · error · java.lang.IllegalArgumentException
Given message schema
Error message
Given message schema: '%s'%ndoes not match schema inferred from protobuf class.%nProtobuf class: '%s'%nInferred schema: '%s'
What it means
ProtoPayloadSerializerProvider verifies that the schema supplied by the caller (requiredSchema) is assignable from the schema inferred from the protobuf class. If they diverge, it throws this IllegalArgumentException showing both schemas, preventing silently wrong serialization of rows to proto bytes.
Solutions
- Regenerate/refresh the required schema from the current .proto definition so both sides match.
- Align field names and types between the table schema and the proto message.
- Print/compare the inferred schema in the message against requiredSchema and fix mismatches.
- Ensure the same protoClass is used to infer the schema as is configured.
Example fix
// before
Schema required = Schema.of(Field.of("id", FieldType.STRING)); // proto id is INT64
// after
Schema required = Schema.of(Field.of("id", FieldType.INT64)); Defensive patterns
Strategy: validation
Validate before calling
Schema inferred = new ProtoMessageSchema().schemaFor(TypeDescriptor.of(protoClass));
if (!inferred.assignableTo(requiredSchema)) {
throw new IllegalArgumentException("schema drift for " + protoClass.getName());
} Try / catch
try { serializer = provider.getSerializer(params); } catch (IllegalArgumentException e) { log.error("schema mismatch: {}", e.getMessage()); throw e; } Prevention
- Derive required schema from the proto class, not by hand.
- Re-derive schemas whenever the .proto changes.
- Keep one source of truth for the schema in config.
When it happens
Trigger: Calling getSerializer with a table schema that doesn't match the schema ProtoMessageSchema infers from the protoClass — e.g. fields added/removed/renamed in the .proto file or the table schema, type changes (int64 vs string), or the .proto was regenerated after the schema was defined.
Common situations: Proto definition updated (new field, changed type) but stored schema/config not updated; hand-written schema with a typo; using a different protoClass than the one the schema was built for.
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
- Cannot create creator for
- Could not decode bytes as message
- Could not encode message as bytes
- DynamicMessage is not allowed for the standard…
- Encountered UNSPECIFIED AtomicType
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/7c2290cfc1a395d7.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoPayloadSerializerProvider.java:59
}
private static Class<? extends Message> getClass(Map<String, Object> tableParams) {
String protoClassName = checkArgumentNotNull(tableParams.get("protoClass")).toString();
try {
Class<?> protoClass = Class.forName(protoClassName);
return protoClass.asSubclass(Message.class);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Incorrect proto class provided: " + protoClassName, e);
}
}
private static <T extends Message> void inferAndVerifySchema(
Class<T> protoClass, Schema requiredSchema) {
@Nonnull
Schema inferredSchema =
checkArgumentNotNull(new ProtoMessageSchema().schemaFor(TypeDescriptor.of(protoClass)));
if (!inferredSchema.assignableTo(requiredSchema)) {
throw new IllegalArgumentException(
String.format(
"Given message schema: '%s'%n"
+ "does not match schema inferred from protobuf class.%n"
+ "Protobuf class: '%s'%n"
+ "Inferred schema: '%s'",
requiredSchema, protoClass.getName(), inferredSchema));
}
}
@Override
public PayloadSerializer getSerializer(Schema schema, Map<String, Object> tableParams) {
Class<? extends Message> protoClass = getClass(tableParams);
inferAndVerifySchema(protoClass, schema);
SimpleFunction<byte[], Row> toRowFn = ProtoMessageSchema.getProtoBytesToRowFn(protoClass);
return PayloadSerializer.of(
ProtoMessageSchema.getRowToProtoBytesFn(protoClass),
bytes -> {
Row rawRow = toRowFn.apply(bytes);View on GitHub (pinned to 12126d8942)