grpc/grpc-go · warning

%q contains invalid substring

Error message

%q contains invalid substring

What it means

Raised by parseMethodConfigAndSuffix when the method config token does not match the regex `^([\w./]+)/((?:\w+)|[*])(.+)?$`. The parser expects `service/method` or `service/method{suffix}` where the service allows word chars, dots, and slashes and the method is either a word or `*`. Any other shape produces this error.

Source

Thrown at internal/binarylog/env_config.go:149

	headerMessageConfigRegexpStr = `^{h` + optionalLengthRegexpStr + `;m` + optionalLengthRegexpStr + `}$`
)

var (
	longMethodConfigRegexp    = regexp.MustCompile(longMethodConfigRegexpStr)
	headerConfigRegexp        = regexp.MustCompile(headerConfigRegexpStr)
	messageConfigRegexp       = regexp.MustCompile(messageConfigRegexpStr)
	headerMessageConfigRegexp = regexp.MustCompile(headerMessageConfigRegexpStr)
)

// Turn "service/method{h;m}" into "service", "method", "{h;m}".
func parseMethodConfigAndSuffix(c string) (service, method, suffix string, _ error) {
	// Regexp result:
	//
	// in:  "p.s/m{h:123,m:123}",
	// out: []string{"p.s/m{h:123,m:123}", "p.s", "m", "{h:123,m:123}"},
	match := longMethodConfigRegexp.FindStringSubmatch(c)
	if match == nil {
		return "", "", "", fmt.Errorf("%q contains invalid substring", c)
	}
	service = match[1]
	method = match[2]
	suffix = match[3]
	return
}

// Turn "{h:123;m:345}" into 123, 345.
//
// Return maxUInt if length is unspecified.
func parseHeaderMessageLengthConfig(c string) (hdrLenStr, msgLenStr uint64, err error) {
	if c == "" {
		return maxUInt, maxUInt, nil
	}
	// Header config only.
	if match := headerConfigRegexp.FindStringSubmatch(c); match != nil {
		if s := match[1]; s != "" {
			hdrLenStr, err = strconv.ParseUint(s, 10, 64)

View on GitHub (pinned to 0c51461d27)

Solutions

  1. Verify the offending token matches `service/method` (service: [\w./]+, method: \w+ or `*`).
  2. Remove any whitespace, smart quotes, or stray commas around the token.
  3. Escape or rename methods whose names use characters outside `\w`; binary-log configs cannot express them.
  4. Test the string by calling NewLoggerFromConfigString in a unit test and checking the warning output.

Example fix

// before
GRPC_BINARY_LOG_FILTER="Foo/Bar-Baz"
// after
GRPC_BINARY_LOG_FILTER="Foo/BarBaz"
Defensive patterns

Strategy: validation

Validate before calling

var methodTokenRe = regexp.MustCompile(`^[\w./]+/(?:\w+|\*)(?:\{.*\})?$`)
func validMethodToken(tok string) bool {
    tok = strings.TrimSpace(tok)
    if tok == "" { return false }
    if strings.HasPrefix(tok, "-") { tok = tok[1:] }
    if strings.HasPrefix(tok, "*") { return true }
    return methodTokenRe.MatchString(tok)
}

Try / catch

Loop over comma-split tokens and validate each with the regex above before passing the full string to NewLoggerFromConfigString; reject early with a clear error.

Prevention

When it happens

Trigger: A token with no slash (e.g. `Foo`), a method containing illegal characters (e.g. `Foo/Bar-Baz`), a leading character other than `-`/`*`/word-char, or stray whitespace like ` Foo/Bar`. An empty token is caught earlier, but a token of only separators like `/Foo` also fails here.

Common situations: Typing a filter by hand with a hyphen, underscore-with-other-chars, or space; pasting a config with smart quotes or trailing commas that produce an empty/odd token; using a fully-qualified proto name with characters the regex disallows.

Related errors


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