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 err

View on GitHub (pinned to 24529f1404)

Solutions

  1. Fix the caller to send a standard gRPC path of the form "/package.Service/Method" (leading slash, exactly one service segment, one method segment).
  2. If the request is not real gRPC, omit or fix the ":path" header so ReadHeader falls back to the headers.Request/headers.Endpoint branch.
  3. Log the raw ":path" value at the gateway/proxy layer and correct the rewrite rule that is mangling it.
  4. 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

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


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/65fe4f891902517d. Report an issue: GitHub.