grpc/grpc-go · error

empty suffix is not allowed in StringMatcher

Error message

empty suffix is not allowed in StringMatcher

What it means

Returned by StringMatcherFromProto (string_matcher.go:112-113) for the Suffix match variant when the suffix string is empty. Like the prefix case, an empty suffix would trivially match every input and is treated as a config error.

Source

Thrown at internal/xds/matcher/string_matcher.go:113

//
// Returns a non-nil error if matcherProto is invalid.
func StringMatcherFromProto(matcherProto *v3matcherpb.StringMatcher) (StringMatcher, error) {
	if matcherProto == nil {
		return StringMatcher{}, errors.New("input StringMatcher proto is nil")
	}

	matcher := StringMatcher{ignoreCase: matcherProto.GetIgnoreCase()}
	switch mt := matcherProto.GetMatchPattern().(type) {
	case *v3matcherpb.StringMatcher_Exact:
		matcher.exactMatch = newStrPtr(&mt.Exact, matcher.ignoreCase)
	case *v3matcherpb.StringMatcher_Prefix:
		if matcherProto.GetPrefix() == "" {
			return StringMatcher{}, errors.New("empty prefix is not allowed in StringMatcher")
		}
		matcher.prefixMatch = newStrPtr(&mt.Prefix, matcher.ignoreCase)
	case *v3matcherpb.StringMatcher_Suffix:
		if matcherProto.GetSuffix() == "" {
			return StringMatcher{}, errors.New("empty suffix is not allowed in StringMatcher")
		}
		matcher.suffixMatch = newStrPtr(&mt.Suffix, matcher.ignoreCase)
	case *v3matcherpb.StringMatcher_SafeRegex:
		regex := matcherProto.GetSafeRegex().GetRegex()
		re, err := CompileSafeRegex(regex)
		if err != nil {
			return StringMatcher{}, fmt.Errorf("safe_regex matcher %q is invalid", regex)
		}
		matcher = NewRegexStringMatcher(re)
	case *v3matcherpb.StringMatcher_Contains:
		if matcherProto.GetContains() == "" {
			return StringMatcher{}, errors.New("empty contains is not allowed in StringMatcher")
		}
		matcher.containsMatch = newStrPtr(&mt.Contains, matcher.ignoreCase)
	default:
		return StringMatcher{}, fmt.Errorf("unrecognized string matcher: %+v", matcherProto)
	}
	return matcher, nil

View on GitHub (pinned to 03255a9237)

Solutions

  1. Set a non-empty suffix value in the StringMatcher.
  2. If all-match is intended, remove the suffix matcher or use an always-allow rule.
  3. Validate generated matchers reject empty suffix values before publishing.

Example fix

// before: { "suffix": "" }
// after:  { "suffix": ".example.com" }
Defensive patterns

Strategy: validation

Validate before calling

func validSuffixStringMatcher(m *v3matcherpb.StringMatcher) error {
    if m.GetSuffix() == "" {
        return errors.New("suffix matcher must have a non-empty suffix")
    }
    return nil
}

Prevention

When it happens

Trigger: A StringMatcher proto whose match pattern is StringMatcher_Suffix with Suffix="". The switch detects the Suffix case, checks GetSuffix()=="", and returns the error.

Common situations: Templated/generated RBAC or route config where a suffix variable resolved to empty; porting a rule that intended a wildcard but used an empty suffix.

Related errors


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