{"record":{"id":"7c2290cfc1a395d7","repo":"apache/beam","slug":"given-message-schema-s-ndoes-not-match-schema-inferred-from","errorCode":null,"errorMessage":"Given message schema: '%s'%ndoes not match schema inferred from protobuf class.%nProtobuf class: '%s'%nInferred schema: '%s'","messagePattern":"Given message schema: '(.+?)'%ndoes not match schema inferred from protobuf class\\.%nProtobuf class: '(.+?)'%nInferred schema: '(.+?)'","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoPayloadSerializerProvider.java","lineNumber":59,"sourceCode":"  }\n\n  private static Class<? extends Message> getClass(Map<String, Object> tableParams) {\n    String protoClassName = checkArgumentNotNull(tableParams.get(\"protoClass\")).toString();\n    try {\n      Class<?> protoClass = Class.forName(protoClassName);\n      return protoClass.asSubclass(Message.class);\n    } catch (ClassNotFoundException e) {\n      throw new IllegalArgumentException(\"Incorrect proto class provided: \" + protoClassName, e);\n    }\n  }\n\n  private static <T extends Message> void inferAndVerifySchema(\n      Class<T> protoClass, Schema requiredSchema) {\n    @Nonnull\n    Schema inferredSchema =\n        checkArgumentNotNull(new ProtoMessageSchema().schemaFor(TypeDescriptor.of(protoClass)));\n    if (!inferredSchema.assignableTo(requiredSchema)) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Given message schema: '%s'%n\"\n                  + \"does not match schema inferred from protobuf class.%n\"\n                  + \"Protobuf class: '%s'%n\"\n                  + \"Inferred schema: '%s'\",\n              requiredSchema, protoClass.getName(), inferredSchema));\n    }\n  }\n\n  @Override\n  public PayloadSerializer getSerializer(Schema schema, Map<String, Object> tableParams) {\n    Class<? extends Message> protoClass = getClass(tableParams);\n    inferAndVerifySchema(protoClass, schema);\n    SimpleFunction<byte[], Row> toRowFn = ProtoMessageSchema.getProtoBytesToRowFn(protoClass);\n    return PayloadSerializer.of(\n        ProtoMessageSchema.getRowToProtoBytesFn(protoClass),\n        bytes -> {\n          Row rawRow = toRowFn.apply(bytes);","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoPayloadSerializerProvider.java#L41-L77","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nSchema required = Schema.of(Field.of(\"id\", FieldType.STRING)); // proto id is INT64\n// after\nSchema required = Schema.of(Field.of(\"id\", FieldType.INT64));","handlingStrategy":"validation","validationCode":"Schema inferred = new ProtoMessageSchema().schemaFor(TypeDescriptor.of(protoClass));\nif (!inferred.assignableTo(requiredSchema)) {\n  throw new IllegalArgumentException(\"schema drift for \" + protoClass.getName());\n}","typeGuard":null,"tryCatchPattern":"try { serializer = provider.getSerializer(params); } catch (IllegalArgumentException e) { log.error(\"schema mismatch: {}\", e.getMessage()); throw e; }","preventionTips":["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."],"tags":["java","protobuf","schema","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}