grpc/grpc-go · error

rbac: error parsing config

Error message

rbac: error parsing config %v: unknown type %T

What it means

ParseFilterConfig (rbac.go:190) requires cfg to be *anypb.Any. The type assertion fails for any other concrete proto.Message type (e.g., passing the *rpb.RBAC directly instead of wrapping it in an Any).

Solutions

  1. Wrap the rpb.RBAC proto in an anypb.Any via anypb.New before passing.
  2. Verify the type URL matches one of the builder's TypeURLs() (RBAC or RBACPerRoute).
  3. Use TypeURLs() as the canonical list of acceptable URLs.

Example fix

// before
cfg, err := rbacBuilder.ParseFilterConfig(&rpb.RBAC{Rules: ...})

// after
anyCfg, _ := anypb.New(&rpb.RBAC{Rules: ...})
cfg, err := rbacBuilder.ParseFilterConfig(anyCfg)
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := cfg.(*anypb.Any); !ok {
    return nil, fmt.Errorf("rbac: expected *anypb.Any, got %T", cfg)
}

Type guard

func isAnyPB(m proto.Message) bool { _, ok := m.(*anypb.Any); return ok }

Try / catch

if _, ok := cfg.(*anypb.Any); !ok {
    anyCfg, err := anypb.New(cfg)
    if err != nil { return err }
    cfg = anyCfg
}
fc, err := rbacBuilder.ParseFilterConfig(cfg)

Prevention

When it happens

Trigger: ParseFilterConfig is called with a proto.Message that is not *anypb.Any — most commonly a *rpb.RBAC or a *v3rbacpb.RBAC passed directly, or a different filter's config.

Common situations: Programmatic test/registration passing the unwrapped proto; control-plane bug sending the raw proto; cross-wiring configs between filters.

Related errors


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

Appendix: source

Thrown at internal/xds/httpfilter/rbac/rbac.go:191

	if name == ":scheme" {
		return fmt.Errorf("rbac: header matcher for %q is %q", name, ":scheme")
	}
	if strings.HasPrefix(name, "grpc-") {
		return fmt.Errorf("rbac: header matcher for %q starts with %q", name, "grpc-")
	}
	if name == "host" {
		header.Name = ":authority"
	}
	return nil
}

func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
	if cfg == nil {
		return nil, fmt.Errorf("rbac: nil configuration message provided")
	}
	m, ok := cfg.(*anypb.Any)
	if !ok {
		return nil, fmt.Errorf("rbac: error parsing config %v: unknown type %T", cfg, cfg)
	}
	msg := new(rpb.RBAC)
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("rbac: error parsing config %v: %v", cfg, err)
	}
	return parseConfig(msg)
}

func (builder) ParseFilterConfigOverride(override proto.Message) (httpfilter.FilterConfig, error) {
	if override == nil {
		return nil, fmt.Errorf("rbac: nil configuration message provided")
	}
	m, ok := override.(*anypb.Any)
	if !ok {
		return nil, fmt.Errorf("rbac: error parsing override config %v: unknown type %T", override, override)
	}
	msg := new(rpb.RBACPerRoute)
	if err := m.UnmarshalTo(msg); err != nil {

View on GitHub (pinned to 0c51461d27)