grpc/grpc-go · error

invalid method string

Error message

invalid method string: %v, err: %v

What it means

validateMethodString rejected an entry in a cloud_logging client_rpc_events/server_rpc_events methods list. The format must be <service>/<method> with no leading slash, exactly one slash, a non-empty method, and the service must not be the wildcard '*'. The wrapped error names the exact rule that failed (leading slash, missing/multiple slash, empty method, or service wildcard).

Solutions

  1. Edit the offending entry to the canonical form <package>.<Service>/<Method>, e.g. "foo.Bar/Baz", no leading slash.
  2. To match all methods of a service use <package>.<Service>/* (e.g. "foo.Bar/*"); to match everything use the single entry "*".
  3. Never set the service component to '*' — "*/Baz" is unsupported; use "*" by itself instead.
  4. Reload the config / restart the process so observability.Start re-parses cleanly.

Example fix

// before (config JSON)
"client_rpc_events":[{"methods":["/foo.Bar/Baz"]}]

// after
"client_rpc_events":[{"methods":["foo.Bar/Baz"]}]
Defensive patterns

Strategy: validation

Validate before calling

func validateMethodString(method string) error {
    if strings.HasPrefix(method, "/") { return errors.New("leading slash") }
    parts := strings.Split(method, "/")
    if len(parts) != 2 { return errors.New("exactly one slash") }
    if parts[1] == "" { return errors.New("empty method") }
    if parts[0] == "*" { return errors.New("service wildcard") }
    return nil
}

// call before observability.Start
for _, m := range cfgMethodList {
    if m != "*" {
        if err := validateMethodString(m); err != nil { return err }
    }
}

Try / catch

if err := observability.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "invalid method string") {
        return fmt.Errorf("observability config has a bad method filter: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Setting a methods entry like "/foo.Bar/Baz" (leading slash), "foo.Bar" (no slash), "foo.Bar/Baz/Qux" (two slashes), "foo.Bar/" (empty method), or "*/Baz" (service wildcard not allowed). Triggered at observability.Start when GRPC_GCP_OBSERVABILITY_CONFIG or the config file is parsed.

Common situations: Copying the gRPC method string from a wire log (which has a leading slash) into the config; using a service-level wildcard expecting it to match all methods of every service; trailing slash typos; YAML-to-JSON conversion dropping the slash; forgetting the package prefix so authors try '/'-based workarounds.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/d23b19de3c2500f0. Report an issue: GitHub.

Appendix: source

Thrown at gcp/observability/config.go:85

	if serviceMethod[1] == "" {
		return errors.New("method name must be non empty")
	}
	if serviceMethod[0] == "*" {
		return errors.New("cannot have service wildcard * i.e. (*/m)")
	}
	return nil
}

func validateLogEventMethod(methods []string, exclude bool) error {
	for _, method := range methods {
		if method == "*" {
			if exclude {
				return errors.New("cannot have exclude and a '*' wildcard")
			}
			continue
		}
		if err := validateMethodString(method); err != nil {
			return fmt.Errorf("invalid method string: %v, err: %v", method, err)
		}
	}
	return nil
}

func validateLoggingEvents(config *config) error {
	if config.CloudLogging == nil {
		return nil
	}
	for _, clientRPCEvent := range config.CloudLogging.ClientRPCEvents {
		if err := validateLogEventMethod(clientRPCEvent.Methods, clientRPCEvent.Exclude); err != nil {
			return fmt.Errorf("error in clientRPCEvent method: %v", err)
		}
	}
	for _, serverRPCEvent := range config.CloudLogging.ServerRPCEvents {
		if err := validateLogEventMethod(serverRPCEvent.Methods, serverRPCEvent.Exclude); err != nil {
			return fmt.Errorf("error in serverRPCEvent method: %v", err)
		}

View on GitHub (pinned to 0c51461d27)