grpc/grpc-go · error

gcpauthn: failed to unmarshal filter config

Error message

gcpauthn: failed to unmarshal filter config: %v

What it means

ParseFilterConfig (gcp_authn_filter.go:68) type-asserted *anypb.Any but UnmarshalTo into GcpAuthnFilterConfig failed. The wrapped bytes are not a valid GcpAuthnFilterConfig: wrong type URL, corrupt payload, or schema mismatch.

Solutions

  1. Ensure the anypb.Any type_url is type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v3.GcpAuthnFilterConfig.
  2. Align go-control-plane versions between server and client.
  3. Log the wrapped error to distinguish type-URL mismatch from wire-format errors.

Example fix

// before
anyCfg := &anypb.Any{TypeUrl: "type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v2.GcpAuthnFilterConfig", Value: raw}

// after
anyCfg := &anypb.Any{TypeUrl: "type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v3.GcpAuthnFilterConfig", Value: raw}
Defensive patterns

Strategy: validation

Validate before calling

if m, ok := cfg.(*anypb.Any); ok {
    want := "type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v3.GcpAuthnFilterConfig"
    if m.TypeUrl != want {
        return nil, fmt.Errorf("gcpauthn: type_url %q != %q", m.TypeUrl, want)
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to unmarshal filter config") {
    // log err to distinguish type-URL mismatch from wire corruption
}

Prevention

When it happens

Trigger: anypb.Any with a mismatched type URL, truncated/malformed bytes, or a go-control-plane version whose GcpAuthnFilterConfig schema differs from the client's compiled proto.

Common situations: Version skew between control-plane and data-plane; corrupted config in transit; wrong filter config bound to the gcp_authn TypeURL.

Related errors


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

Appendix: source

Thrown at internal/xds/httpfilter/gcp_authn/gcp_authn_filter.go:69

type builder struct{}

type config struct {
	httpfilter.FilterConfig
	cacheSize uint64
}

func (builder) TypeURLs() []string {
	return []string{"type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v3.GcpAuthnFilterConfig"}
}

func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
	m, ok := cfg.(*anypb.Any)
	if !ok {
		return nil, fmt.Errorf("gcpauthn: invalid filter config type %T", cfg)
	}
	msg := &v3gcpauthnpb.GcpAuthnFilterConfig{}
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("gcpauthn: failed to unmarshal filter config: %v", err)
	}

	cacheSize := uint64(defaultCacheSize)
	if cacheSizeConfig := msg.GetCacheConfig().GetCacheSize(); cacheSizeConfig != nil {
		if cacheSize = cacheSizeConfig.GetValue(); cacheSize == 0 {
			return nil, fmt.Errorf("gcpauthn: cache_config.cache_size must be greater than zero")
		}
	}

	return config{cacheSize: cacheSize}, nil
}

// ParseFilterConfigOverride parses the provided override configuration.
//
// Note that we don't support overrides for this filter configuration,
// but still validate it as part of the normal resource validation.
func (b builder) ParseFilterConfigOverride(cfg proto.Message) (httpfilter.FilterConfig, error) {
	return b.ParseFilterConfig(cfg)

View on GitHub (pinned to 0c51461d27)