grpc/grpc-go · error

unknown header matcher type

Error message

unknown header matcher type

What it means

Returned by newHeaderMatcher (rbac/matchers.go:325) when the HeaderMatcher proto's HeaderMatchSpecifier oneof is set to a variant not handled by the type switch (exact, safe_regex, range, present, prefix, suffix, contains, string_match). The default branch covers any new Envoy header matcher type this gRPC build does not yet understand, failing loudly rather than silently ignoring the rule.

Source

Thrown at internal/xds/rbac/matchers.go:325

		m = internalmatcher.NewHeaderRegexMatcher(headerMatcherConfig.Name, regex, headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_RangeMatch:
		m = internalmatcher.NewHeaderRangeMatcher(headerMatcherConfig.Name, headerMatcherConfig.GetRangeMatch().Start, headerMatcherConfig.GetRangeMatch().End, headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_PresentMatch:
		m = internalmatcher.NewHeaderPresentMatcher(headerMatcherConfig.Name, headerMatcherConfig.GetPresentMatch(), headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_PrefixMatch:
		m = internalmatcher.NewHeaderPrefixMatcher(headerMatcherConfig.Name, headerMatcherConfig.GetPrefixMatch(), headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_SuffixMatch:
		m = internalmatcher.NewHeaderSuffixMatcher(headerMatcherConfig.Name, headerMatcherConfig.GetSuffixMatch(), headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_ContainsMatch:
		m = internalmatcher.NewHeaderContainsMatcher(headerMatcherConfig.Name, headerMatcherConfig.GetContainsMatch(), headerMatcherConfig.InvertMatch)
	case *v3route_componentspb.HeaderMatcher_StringMatch:
		sm, err := internalmatcher.StringMatcherFromProto(headerMatcherConfig.GetStringMatch())
		if err != nil {
			return nil, fmt.Errorf("invalid string matcher %+v: %v", headerMatcherConfig.GetStringMatch(), err)
		}
		m = internalmatcher.NewHeaderStringMatcher(headerMatcherConfig.Name, sm, headerMatcherConfig.InvertMatch)
	default:
		return nil, errors.New("unknown header matcher type")
	}
	return &headerMatcher{matcher: m}, nil
}

func (hm *headerMatcher) match(data *rpcData) bool {
	return hm.matcher.Match(data.md)
}

// urlPathMatcher matches on the URL Path of the incoming RPC. In gRPC, this
// logically maps to the full method name the RPC is calling on the server side.
// urlPathMatcher implements the matcher interface.
type urlPathMatcher struct {
	stringMatcher internalmatcher.StringMatcher
}

func newURLPathMatcher(pathMatcher *v3matcherpb.PathMatcher) (*urlPathMatcher, error) {
	stringMatcher, err := internalmatcher.StringMatcherFromProto(pathMatcher.GetPath())
	if err != nil {

View on GitHub (pinned to 03255a9237)

Solutions

  1. Upgrade the gRPC client to a version that supports the header matcher type in use.
  2. Downgrade or reconfigure the control plane to emit only supported HeaderMatcher variants (exact/regex/range/present/prefix/suffix/contains/string).
  3. Inspect the offending HeaderMatcher proto (log HeaderMatchSpecifier) to identify which variant is unsupported and adjust the policy.

Example fix

// before: policy uses a header matcher variant gRPC does not know
// after:  rewrite the RBAC rule using a supported matcher, e.g.
//   header: { name: "x-env", exact_match: "true" }
Defensive patterns

Strategy: validation

Validate before calling

// Before publishing an RBAC/route config, ensure every header matcher uses a
// supported HeaderMatchSpecifier variant.
var supportedHeaderMatchers = map[reflect.Type]bool{
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_ExactMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_SafeRegexMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_RangeMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_PresentMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_PrefixMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_SuffixMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_ContainsMatch{}): true,
    reflect.TypeOf(&v3route_componentspb.HeaderMatcher_StringMatch{}): true,
}
func hmIsSupported(hm *v3route_componentspb.HeaderMatcher) bool {
    return hm != nil && supportedHeaderMatchers[reflect.TypeOf(hm.HeaderMatchSpecifier)]
}

Prevention

When it happens

Trigger: An RBAC or route configuration uses a HeaderMatcher oneof variant introduced by a newer Envoy/xDS version than the gRPC client supports. The switch falls through to default and returns 'unknown header matcher type'.

Common situations: Control plane running a newer Envoy that emits a header matcher type (e.g. a new match variant) not implemented in this gRPC release; upgrading Envoy ahead of gRPC; custom envoy extensions adding matcher types.

Related errors


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