grpc-ecosystem/grpc-gateway · error

no message found: %s

Error message

no message found: %s

What it means

Registry.LookupMsg fails when the requested message name starts with '.' (a fully-qualified name) and is not present in the registry's message map. It means no message with that exact fully-qualified name was loaded from any proto file.

Source

Thrown at internal/descriptor/registry.go:359

		}
		file.Enums = append(file.Enums, e)
		r.enums[e.FQEN()] = e
		if grpclog.V(1) {
			grpclog.Infof("Register enum name: %s", e.FQEN())
		}
	}
}

// LookupMsg looks up a message type by "name".
// It tries to resolve "name" from "location" if "name" is a relative message name.
func (r *Registry) LookupMsg(location, name string) (*Message, error) {
	if grpclog.V(1) {
		grpclog.Infof("Lookup %s from %s", name, location)
	}
	if strings.HasPrefix(name, ".") {
		m, ok := r.msgs[name]
		if !ok {
			return nil, fmt.Errorf("no message found: %s", name)
		}
		return m, nil
	}

	if !strings.HasPrefix(location, ".") {
		location = fmt.Sprintf(".%s", location)
	}
	components := strings.Split(location, ".")
	for len(components) > 0 {
		fqmn := strings.Join(append(components, name), ".")
		if m, ok := r.msgs[fqmn]; ok {
			return m, nil
		}
		components = components[:len(components)-1]
	}
	return nil, fmt.Errorf("no message found: %s", name)
}

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Load the proto file that defines the message (registry.LoadFile / pass it to protoc)
  2. Verify the fully-qualified name matches package + message (and nesting) exactly
  3. Check for package renames and update references
  4. Enable grpclog V(1) logging to see lookup location context

Example fix

// before (message not loaded)
reg.LoadFile("service.proto")
m, err := reg.LookupMsg(".example.hello.Greeter", ".example.hello.MissingRequest")
// after
reg.LoadFile("message.proto") // defines .example.hello.MissingRequest
reg.LoadFile("service.proto")
m, err := reg.LookupMsg(".example.hello.Greeter", ".example.hello.MissingRequest")
Defensive patterns

Strategy: try-catch

Validate before calling

func hasMsg(reg *Registry, fqmn string) bool {
    _, err := reg.LookupMsg(".", fqmn)
    return err == nil
}

Try / catch

m, err := reg.LookupMsg(loc, ".example.hello.HelloRequest")
if err != nil {
    return fmt.Errorf("message %s not loaded: ensure its proto file is loaded first: %w", name, err)
}

Prevention

When it happens

Trigger: LookupMsg(location, name) with name like '.example.hello.HelloRequest' when that message was never loaded (missing proto file) or the fully-qualified name is misspelled (wrong package or nested path).

Common situations: Referencing a message from a proto file not passed to the registry; package renamed in proto but not in annotations/config; typos in .proto FQMN in grpc API configuration files.

Related errors


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/f3f355cfcf01b0eb. Report an issue: GitHub.