XINCGer/Unity3DTraining · error · DescriptorValidationException
Messages can't have default values.
Error message
Messages can't have default values.
What it means
Proto3/message-typed fields cannot carry a default value; defaults only apply to scalar fields (proto2). During CrossLink, after resolving a message-typed field, a non-empty Proto.DefaultValue triggers DescriptorValidationException.
Solutions
- Remove the DefaultValue from the message-typed field's proto and regenerate.
- Set message fields via initialization in code after parsing instead of via default_value.
- Strip/ignore default_value for message fields when importing descriptors from external sources.
Example fix
// before
new FieldDescriptorProto { Name = "addr", Type = TYPE_MESSAGE, TypeName = "Address", DefaultValue = "" }
// after
new FieldDescriptorProto { Name = "addr", Type = TYPE_MESSAGE, TypeName = "Address" } Defensive patterns
Strategy: validation
Validate before calling
if (field.Proto.Type == FieldDescriptorProto.Types.Type.Message && field.Proto.DefaultValue != "")
throw new InvalidDataException("Message field " + field.Name + " must not have a default value"); Type guard
bool HasNoMessageDefault(FieldDescriptorProto f) =>
f.Type != FieldDescriptorProto.Types.Type.Message || string.IsNullOrEmpty(f.DefaultValue); Try / catch
try { descriptor = FileDescriptor.BuildFromByteStrings(data); }
catch (DescriptorValidationException ex) when (ex.Message == "Messages can't have default values.")
{ log.LogError(ex, "Remove default_value from message-typed fields"); } Prevention
- Never set default_value on message or enum-typed fields.
- Strip DefaultValue when sanitizing externally supplied descriptors.
- Initialize message fields in application code instead of via descriptor defaults.
When it happens
Trigger: A FieldDescriptorProto with Type = TYPE_MESSAGE and a non-empty DefaultValue string — e.g. hand-built descriptors, descriptors edited by tools, or protos written with invalid default_value on a message field.
Common situations: Porting proto2 scalar field configs onto message fields; code generators that emit default_value unconditionally; manual editing of descriptor sets.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- FieldDescriptorProto.oneof_index is out of range for type
- Invalid type specified
- "TypeName" is not a type.
- "TypeName" is not a message type.
- "TypeName" is not an enum type.
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/87332da8159de264.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs:331
fieldType = FieldType.Enum;
}
else
{
throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
}
}
if (fieldType == FieldType.Message)
{
if (!(typeDescriptor is MessageDescriptor))
{
throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a message type.");
}
messageType = (MessageDescriptor)typeDescriptor;
if (Proto.DefaultValue != "")
{
throw new DescriptorValidationException(this, "Messages can't have default values.");
}
}
else if (fieldType == FieldType.Enum)
{
if (!(typeDescriptor is EnumDescriptor))
{
throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
}
enumType = (EnumDescriptor)typeDescriptor;
}
else
{
throw new DescriptorValidationException(this, "Field with primitive type has type_name.");
}
}
else
{
if (fieldType == FieldType.Message || fieldType == FieldType.Enum)View on GitHub (pinned to 016f98412e)