XINCGer/Unity3DTraining · error · DescriptorValidationException
MessageSet format is not supported.
Error message
MessageSet format is not supported.
What it means
Google.Protobuf does not support the proto2 MessageSet wire format option. CrossLink checks the containing type's MessageSetWireFormat option and throws DescriptorValidationException if it is true, because message-set fields cannot be represented by this runtime.
Solutions
- Remove `option message_set_wire_format = true;` from the message and use ordinary fields or groups instead.
- Regenerate code/descriptors with protoc after removing the option.
- If MessageSet is required, use a runtime that supports it; the C# Google.Protobuf port intentionally does not.
- Rewrite MessageSet-style extension usage as regular repeated fields.
Example fix
// before (proto)
message LegacyEvent { option message_set_wire_format = true; }
// after (proto)
message LegacyEvent { repeated ExtendedData data = 1; } // drop message_set_wire_format Defensive patterns
Strategy: validation
Validate before calling
bool MessageSetFree(FileDescriptorProto f) => f.MessageType.All(m => m.Options == null || !m.Options.MessageSetWireFormat);
Try / catch
try { BuildFrom(...); } catch (DescriptorValidationException e) when (e.Message.Contains("MessageSet")) { throw new NotSupportedException("MessageSet format is unsupported in Google.Protobuf (C#)"); } Prevention
- Never enable message_set_wire_format in .proto files targeting C#.
- Document MessageSet incompatibility when sharing schemas with C++/Java teams.
- Prefer ordinary repeated fields for extensibility.
When it happens
Trigger: A message in the descriptor has options.message_set_wire_format = true (e.g. compatibility descriptors ported from C++/Java code that uses MessageSet, like extensions of google.protobuf.MessageSet or old exproto/LogCollector formats).
Common situations: Porting legacy proto2 schemas that used message sets for extensibility; sharing descriptor files with systems that rely on MessageSet wire format.
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
- Invalid map field:
- " " is already defined (as something other than a package)…
- " " is already defined in file " ".
- Missing name.
- " " is not a valid identifier.
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/e69e541ead17d865.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs:361
{
throw new DescriptorValidationException(this, "Field with primitive type has type_name.");
}
}
else
{
if (fieldType == FieldType.Message || fieldType == FieldType.Enum)
{
throw new DescriptorValidationException(this, "Field with message or enum type missing type_name.");
}
}
// Note: no attempt to perform any default value parsing
File.DescriptorPool.AddFieldByNumber(this);
if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat)
{
throw new DescriptorValidationException(this, "MessageSet format is not supported.");
}
accessor = CreateAccessor();
}
private IFieldAccessor CreateAccessor()
{
// If we're given no property name, that's because we really don't want an accessor.
// (At the moment, that means it's a map entry message...)
if (propertyName == null)
{
return null;
}
var property = ContainingType.ClrType.GetProperty(propertyName);
if (property == null)
{
throw new DescriptorValidationException(this, "Property " + propertyName + " not found in " + ContainingType.ClrType);
}
return IsMap ? new MapFieldAccessor(property, this)View on GitHub (pinned to 016f98412e)