micro/go-micro · error
unknown request path
Error message
unknown request path
What it means
The go-micro gRPC codec parses the HTTP/2 ":path" header of an incoming request to derive the target service and endpoint. It expects exactly the gRPC form "/package.Service/Method", i.e. splitting on "/" must yield exactly 3 parts. If the path header is missing its leading slash, has extra segments, or is otherwise malformed, ReadHeader returns "unknown request path" and the request is rejected before any handler runs.
Source
Thrown at codec/grpc/grpc.go:39
func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
if ct := m.Header["Content-Type"]; len(ct) > 0 {
c.ContentType = ct
}
if ct := m.Header["content-type"]; len(ct) > 0 {
c.ContentType = ct
}
// service method
path := m.Header[":path"]
if len(path) == 0 || path[0] != '/' {
m.Target = m.Header[headers.Request]
m.Endpoint = m.Header[headers.Endpoint]
} else {
// [ , a.package.Foo, Bar]
parts := strings.Split(path, "/")
if len(parts) != 3 {
return errors.New("unknown request path")
}
service := strings.Split(parts[1], ".")
m.Endpoint = strings.Join([]string{service[len(service)-1], parts[2]}, ".")
m.Target = strings.Join(service[:len(service)-1], ".")
}
return nil
}
func (c *Codec) ReadBody(b interface{}) error {
// no body
if b == nil {
return nil
}
_, buf, err := decode(c.Conn)
if err != nil {
return errView on GitHub (pinned to 24529f1404)
Solutions
- Fix the caller to send a standard gRPC path of the form "/package.Service/Method" (leading slash, exactly one service segment, one method segment).
- If the request is not real gRPC, omit or fix the ":path" header so ReadHeader falls back to the headers.Request/headers.Endpoint branch.
- Log the raw ":path" value at the gateway/proxy layer and correct the rewrite rule that is mangling it.
- Ensure client and server go-micro versions agree on how the method path is encoded (upgrade both to the same version).
Example fix
// before (hand-crafted request)
header.Set(":path", "/helloworld.Greeter")
// after
header.Set(":path", "/helloworld.Greeter/SayHello") Defensive patterns
Strategy: validation
Validate before calling
path := header.Get(":path")
if strings.HasPrefix(path, "/") && len(strings.Split(path, "/")) != 3 {
return fmt.Errorf("malformed gRPC path %q: want /package.Service/Method", path)
} Prevention
- Always send standard gRPC "/package.Service/Method" paths from clients and gateways.
- Log the raw :path at proxy boundaries to catch rewrite bugs early.
- Add a test that round-trips every RPC method path through the codec.
- Pin client and server go-micro versions to the same release.
When it happens
Trigger: ReadHeader is called with m.Header[":path"] set to a value starting with '/' (so the gRPC parsing branch is taken) but whose strings.Split(path, "/") does not produce exactly 3 parts — e.g. "/service.Method" (missing method segment), "/a/b/c/d" (extra segments), or a trailing slash like "/pkg.Svc/Method/".
Common situations: Pointing a non-go-micro gRPC client at a go-micro server with an unusual full method name; a proxy or gateway rewriting/trimming the :path; manually hand-crafting gRPC frames in tests with an incorrect path; version drift where an older client encodes the target in a different path layout.
Related errors
- unsupported Content-Type
- ErrInvalidMessage
- failed to marshal: %v is not type of *bytes.Frame or proto.M
- failed to unmarshal: %v is not type of proto.Message
- failed to marshal: %v is not type of *[]byte
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/65fe4f891902517d.
Report an issue: GitHub.