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.
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: is not type of *[]byte
- failed to marshal: is not type of *bytes.Frame or…
- failed to read body: 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.
Appendix: 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)