grpc-ecosystem/grpc-gateway · error
failed to lookup message type %s: %w
Error message
failed to lookup message type %s: %w
What it means
In protoc-gen-grpc-gateway's body-field type resolution (GetBodyFieldType), when a body mapping path component targets a message-typed field, the registry is asked to resolve that type name relative to the parent message. If LookupMsg cannot find the message (unregistered file, wrong name, load-order issue), the code wraps the failure with 'failed to lookup message type %s: %w'. It signals the proto descriptor graph is incomplete or inconsistent for the body path being generated.
Source
Thrown at protoc-gen-grpc-gateway/internal/gengateway/template.go:66
return "", errors.New("no body field found")
}
// GetBodyFieldType returns the Go type of the body field.
func (b binding) GetBodyFieldType() (string, error) {
if b.Body == nil || len(b.Body.FieldPath) == 0 {
return "", errors.New("no body field found")
}
lastComponent := b.Body.FieldPath[len(b.Body.FieldPath)-1]
fieldType := lastComponent.Target.GetType()
// Handle message types
if fieldType == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE {
// Get the parent message to provide proper lookup context
parentMsg := lastComponent.Target.Message
msg, err := b.Registry.LookupMsg(parentMsg.FQMN(), lastComponent.Target.GetTypeName())
if err != nil {
return "", fmt.Errorf("failed to lookup message type %s: %w", lastComponent.Target.GetTypeName(), err)
}
return msg.GoType(b.Method.Service.File.GoPkg.Path), nil
}
return "", errors.New("unsupported body field type")
}
// HasQueryParam determines if the binding needs parameters in query string.
//
// It sometimes returns true even though actually the binding does not need.
// But it is not serious because it just results in a small amount of extra codes generated.
func (b binding) HasQueryParam() bool {
if b.Body != nil && len(b.Body.FieldPath) == 0 {
return false
}
fields := make(map[string]bool)
for _, f := range b.Method.RequestType.Fields {
fields[f.GetName()] = trueView on GitHub (pinned to a58a4436a3)
Solutions
- Ensure every proto dependency (including transitive ones) is passed to protoc so its descriptors are registered with the Registry before generation.
- Regenerate descriptors so the body path's message type name matches the current proto (check lastComponent.Target.GetTypeName() against your .proto files).
- If using RegisterFunc/registry loading, verify LookupMsg-able messages exist — e.g. confirm the message FQMN appears in the registry with a small debug print or registry lookup in a custom plugin.
- Update protoc-gen-grpc-gateway to match your protoc/protoc-gen-go versions and regenerate.
Example fix
// before: protoc foo.proto only, message Bar lives in bar.proto used as body field protoc --grpc-gateway_out=. foo.proto // after: pass all deps protoc -I . --grpc-gateway_out=. foo.proto bar.proto
Defensive patterns
Strategy: validation
Validate before calling
// In a custom plugin/wrapper, before generating:
for _, dep := range allProtoFiles {
if _, err := reg.LookupMsg(parentFQMN, typeName); err != nil {
return fmt.Errorf("missing message %s (from %s): %w", typeName, dep, err)
}
} Prevention
- Always pass all transitive proto dependencies to protoc.
- Regenerate gateway code and descriptors together in CI.
- Keep protoc-gen-grpc-gateway version aligned with protoc/protobuf runtime.
When it happens
Trigger: Calling GetBodyFieldType (during gateway template execution) when lastComponent.Target is TYPE_MESSAGE and Registry.LookupMsg(parentMsg.FQMN(), typeName) fails — e.g. the message's file was never loaded into the Registry, the type name is stale, or external deps weren't imported via WithImportPath/LoadFromPlugin.
Common situations: Generating a gateway for protos that depend on external packages (googleapis annotations, well-known types) without registering those dependency files; renaming/moving a message so body path references no longer resolve; using a plugin version mismatched with regenerated descriptors.
Related errors
- HTTP rules without a matching selector: %s
- unknown enum type %s
- unknown message type %s
- JSON structure did not match request type
- unable to marshal non proto field
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/7a1fa4da1d718248.
Report an issue: GitHub.