apache/beam · error · java.lang.RuntimeException
DynamicMessage is not allowed for the standard…
Error message
DynamicMessage is not allowed for the standard ProtoSchemaProvider, use ProtoDynamicMessageSchema instead.
What it means
The standard ProtoSchemaProvider cannot build a schema for DynamicMessage because field information lives in a runtime Descriptor rather than generated accessors. Beam throws this to steer users to ProtoDynamicMessageSchema, which handles descriptor-based messages.
Solutions
- Use ProtoDynamicMessageSchema / the dynamic message schema provider for DynamicMessage types.
- Switch the PCollection element type to a concrete generated Message class.
- If dynamic parsing is not needed, use ProtoCoder or generated classes.
Example fix
// before schemaRegistry.registerTypeDescriptor(DynamicMessage.class); // after new ProtoDynamicMessageSchema(descriptorForType).schemaFor(TypeDescriptor.of(DynamicMessage.class));
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeDescriptor.getRawType().equals(DynamicMessage.class)) {
// route to ProtoDynamicMessageSchema instead
} Type guard
boolean isDynamic = DynamicMessage.class.equals(type.getRawType());
Try / catch
try { schema = protoSchema.schemaFor(type); } catch (RuntimeException e) { if (e.getMessage().contains("DynamicMessage")) schema = dynamicSchema.schemaFor(type); else throw e; } Prevention
- Never register DynamicMessage with the standard schema provider.
- Use ProtoDynamicMessageSchema for descriptor-based messages.
- Prefer concrete generated classes in schema'd PCollections.
When it happens
Trigger: Calling schemaFor (through checkForDynamicType) with TypeDescriptor.of(DynamicMessage.class), e.g. registering DynamicMessage in a Schema registry or creating a schema'd PCollection of DynamicMessage via the standard provider.
Common situations: Pipelines parsing protos from descriptors at runtime; code that switched from generated messages to DynamicMessage without updating schema configuration.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot create creator for
- Could not decode bytes as message
- Could not encode message as bytes
- Encountered UNSPECIFIED AtomicType
- Failed to decode Schema due to an error decoding Field…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/e56ce76104e83c71.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoMessageSchema.java:154
new ProtoMessageSchema(),
TypeDescriptor.of(protoClass),
bytes -> protoCoder.getParser().parseFrom(bytes));
}
// Other modules are not allowed to use non-vendored Message class
@SuppressWarnings({
"rawtypes", // TODO(https://github.com/apache/beam/issues/20447)
"unchecked"
})
public static <T> SimpleFunction<Row, byte[]> getRowToProtoBytesFn(Class<T> clazz) {
Class<Message> protoClass = ensureMessageType(clazz);
return RowMessages.rowToBytesFn(
new ProtoMessageSchema(), TypeDescriptor.of(protoClass), Message::toByteArray);
}
private <T> void checkForDynamicType(TypeDescriptor<T> typeDescriptor) {
if (typeDescriptor.getRawType().equals(DynamicMessage.class)) {
throw new RuntimeException(
"DynamicMessage is not allowed for the standard ProtoSchemaProvider, use"
+ " ProtoDynamicMessageSchema instead.");
}
}
private static Class<Message> ensureMessageType(Class<?> clazz) {
checkArgument(
Message.class.isAssignableFrom(clazz),
"%s is not a subtype of %s",
clazz.getName(),
Message.class.getSimpleName());
return (Class<Message>) clazz;
}
}
View on GitHub (pinned to 12126d8942)