grpc/grpc-go · error

extauthz: failed to unmarshal config

Error message

extauthz: failed to unmarshal config: %v

What it means

The Any-wrapped configuration could not be unmarshaled into an envoy.extensions.filters.http.ext_authz.v3.ExtAuthz proto (ext_authz.go:98-99). The serialized payload in the Any does not match the ExtAuthz schema or the TypeURL is incorrect.

Solutions

  1. Verify the TypeURL matches 'type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz'
  2. Ensure the xDS server and client use compatible go-control-plane / Envoy proto versions
  3. Use xDS config dump to inspect the raw Any payload for corruption
  4. Check for go-control-plane version mismatches between server and client
Defensive patterns

Strategy: validation

Validate before calling

// Validate the TypeURL before unmarshaling.
const extAuthzTypeURL = "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz"
if anyMsg.TypeUrl != extAuthzTypeURL {
    return fmt.Errorf("unexpected TypeURL %q, want %q", anyMsg.TypeUrl, extAuthzTypeURL)
}

Try / catch

_, err := builder.ParseFilterConfig(anyCfg)
if err != nil && strings.Contains(err.Error(), "failed to unmarshal config") {
    log.Printf("ExtAuthz config unmarshal failed: %v — check TypeURL and proto version", err)
}

Prevention

When it happens

Trigger: anypb.Any.UnmarshalTo(msg) fails because the Any payload is corrupted, truncated, or the TypeURL does not match 'type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz'.

Common situations: xDS server proto version mismatch (different Envoy ext_authz proto revision); TypeURL in the Any does not match the expected v3 ExtAuthz URL; payload corruption in transit; server sends a different filter type under the ext_authz type URL.

Related errors


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

Appendix: source

Thrown at internal/xds/httpfilter/ext_authz/ext_authz.go:99

	return fraction{numerator: num, denominator: den}, nil
}

// grpcStatusCode converts an HTTP status code to a gRPC status code.
func grpcStatusCode(httpStatus int32) codes.Code {
	if code, ok := transport.HTTPStatusConvTab[int(httpStatus)]; ok {
		return code
	}
	return codes.Unknown
}

func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
	m, ok := cfg.(*anypb.Any)
	if !ok {
		return nil, fmt.Errorf("extauthz: error parsing config %v: unknown type %T, want *anypb.Any", cfg, cfg)
	}
	msg := new(v3extauthzpb.ExtAuthz)
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("extauthz: failed to unmarshal config: %v", err)
	}

	if msg.GetGrpcService() == nil {
		return nil, fmt.Errorf("extauthz: empty grpc_service provided in config %v", cfg)
	}
	server, err := parseGRPCServiceConfig(msg.GetGrpcService())
	if err != nil {
		return nil, fmt.Errorf("extauthz: failed to parse grpc_service: %v", err)
	}

	filterEnabled, err := parseFilterEnabled(msg.GetFilterEnabled())
	if err != nil {
		return nil, err
	}

	var denyAtDisable bool
	if denyAtDisableFlag := msg.GetDenyAtDisable(); denyAtDisableFlag != nil {
		if denyAtDisableFlag.GetDefaultValue() == nil {

View on GitHub (pinned to 0c51461d27)