grpc/grpc-go · error

rls: GrpcKeyBuilder in RouteLookupConfig contains a method w

Error message

rls: GrpcKeyBuilder in RouteLookupConfig contains a method with a slash {%+v}

What it means

The library itself constructs the /service/method path from the Name's service and method fields, so the method field must be the bare method name with no slashes. If strings.Contains(method, "/") is true, MakeBuilderMap rejects it because the resulting path would have extra segments and break the path split logic in BuilderMap.RLSKey.

Source

Thrown at balancer/rls/internal/keys/builder.go:94

			constantKeys: constantKeys,
			hostKey:      kb.GetExtraKeys().GetHost(),
			serviceKey:   kb.GetExtraKeys().GetService(),
			methodKey:    kb.GetExtraKeys().GetMethod(),
		}

		// Store the builder created above in the BuilderMap based on the value
		// of the `Names` field, which wraps incoming request's service and
		// method. Also, ensure that there are no repeated `Names` field.
		names := kb.GetNames()
		if len(names) == 0 {
			return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig does not contain any Name {%+v}", kbs)
		}
		for _, name := range names {
			if name.GetService() == "" {
				return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains a Name field with no Service {%+v}", kbs)
			}
			if strings.Contains(name.GetMethod(), `/`) {
				return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains a method with a slash {%+v}", kbs)
			}
			path := "/" + name.GetService() + "/" + name.GetMethod()
			if _, ok := bm[path]; ok {
				return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated Name field {%+v}", kbs)
			}
			bm[path] = b
		}
	}
	return bm, nil
}

// KeyMap represents the RLS keys to be used for a request.
type KeyMap struct {
	// Map is the representation of an RLS key as a Go map. This is used when
	// an actual RLS request is to be sent out on the wire, since the
	// RouteLookupRequest proto expects a Go map.
	Map map[string]string
	// Str is the representation of an RLS key as a string, sorted by keys.

View on GitHub (pinned to 03255a9237)

Solutions

  1. Put only the bare method name in method (e.g. "Get", not "Sub/Get").
  2. If you need a sub-path, encode it differently (the gRPC method name itself cannot contain a slash).
  3. Strip leading/trailing slashes from the method field before validation.

Example fix

// before
{"names":[{"service":"pkg.Svc","method":"Sub/Get"}]}
// after
{"names":[{"service":"pkg.Svc","method":"Get"}]}
Defensive patterns

Strategy: validation

Validate before calling

func validateNameMethodNoSlash(cfg *rlspb.RouteLookupConfig) error {
    for bi, kb := range cfg.GetGrpcKeybuilders() {
        for ni, n := range kb.GetNames() {
            if strings.Contains(n.GetMethod(), "/") {
                return fmt.Errorf("keybuilder[%d].names[%d] method %q contains '/'", bi, ni, n.GetMethod())
            }
        }
    }
    return nil
}

Prevention

When it happens

Trigger: A Name like {service:"pkg.Svc", method:"Sub/Get"} or method:"/Get" — any method containing a '/' character.

Common situations: Putting the full /service/method into the method field; splitting a method name into namespace-like segments with slashes; copy-paste from a path string.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/f5881d9febca5254. Report an issue: GitHub.