grpc/grpc-go · error
rls: method name %q is not of the form '/service/method
Error message
rls: method name %q is not of the form '/service/method
What it means
At the start of every Pick, rlsPicker verifies the RPC's FullMethodName matches the gRPC convention /service/method (one leading slash and exactly two slashes total via isFullMethodNameValid). If not, it refuses to route because the key-builder lookup (which splits on the last slash) would produce garbage keys. This is a runtime error returned from the picker, not a config error.
Source
Thrown at balancer/rls/picker.go:84
grpcTarget string
metricsRecorder estats.MetricsRecorder
defaultPolicy *childPolicyWrapper // Child policy for the default target.
ctrlCh *controlChannel // Control channel to the RLS server.
maxAge time.Duration // Cache max age from LB config.
staleAge time.Duration // Cache stale age from LB config.
bg exitIdler
logger *internalgrpclog.PrefixLogger
}
// isFullMethodNameValid return true if name is of the form `/service/method`.
func isFullMethodNameValid(name string) bool {
return strings.HasPrefix(name, "/") && strings.Count(name, "/") == 2
}
// Pick makes the routing decision for every outbound RPC.
func (p *rlsPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
if name := info.FullMethodName; !isFullMethodNameValid(name) {
return balancer.PickResult{}, fmt.Errorf("rls: method name %q is not of the form '/service/method", name)
}
// Build the request's keys using the key builders from LB config.
md, _ := metadata.FromOutgoingContext(info.Ctx)
reqKeys := p.kbm.RLSKey(md, p.origEndpoint, info.FullMethodName)
p.lb.cacheMu.Lock()
var pr balancer.PickResult
var err error
// Record metrics without the cache mutex held, to prevent lock contention
// between concurrent RPC's and their Pick calls. Metrics Recording can
// potentially be expensive.
metricsCallback := func() {}
defer func() {
p.lb.cacheMu.Unlock()
metricsCallback()
}()View on GitHub (pinned to 03255a9237)
Solutions
- Ensure the RPC is invoked through a normally-generated gRPC client stub so FullMethodName is /package.Service/Method.
- If proxying, normalize the method to /service/method before it reaches the picker.
- Check for interceptors/transformers that strip or mangle the leading slash.
Example fix
// before: invoking with a malformed method conn.NewConn().Invoke(ctx, "Get", req, resp) // after: use the generated stub (method name is /pkg.Svc/Get) client := pb.NewSvcClient(conn) client.Get(ctx, req)
Defensive patterns
Strategy: try-catch
Validate before calling
func isValidFullMethodName(name string) bool {
return strings.HasPrefix(name, "/") && strings.Count(name, "/") == 2
} Try / catch
err := conn.Invoke(ctx, method, req, resp)
if err != nil && strings.Contains(err.Error(), "is not of the form '/service/method") {
// method name is malformed; re-route through a generated stub or normalize method
log.Printf("malformed method name %q; falling back", method)
} Prevention
- Always call RPCs through generated client stubs so FullMethodName is well-formed.
- If proxying, normalize the method to /service/method before invoking.
- Watch for interceptors that strip the leading slash from FullMethodName.
When it happens
Trigger: Calling a gRPC method whose FullMethodName is not of the form /service/method — e.g. "Get", "service/method" (missing leading slash), or "/a/b/c" (three slashes). Typically only seen with custom invocation handlers, in-process servers with malformed method registration, or proxying tooling that fabricates method names.
Common situations: Using grpc.NewServer with a service whose method name was registered oddly; hand-built streaming proxies; test harnesses that invoke Pick directly with an arbitrary string; custom resolver/interceptor rewriting FullMethodName.
Related errors
- RLS response's target list does not contain any entries for
- ringhash: expected xDS config selector to set the request ha
- rls: json unmarshal failed for service config %+v: %v
- rls: bad RouteLookupConfig proto %+v: %v
- rls: bad control channel service config %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/11f78424a86176c9.
Report an issue: GitHub.