grpc/grpc-go · error

extproc: failed to parse grpc_service %v

Error message

extproc: failed to parse grpc_service %v

What it means

Raised by ParseFilterConfig (ext_proc.go:130) when iextproc.ParseGRPCServiceConfig rejects the supplied grpc_service proto. Unlike ext_authz (where the parser is currently a stub), the ext_proc parser is injectable (internal/internal.go:42) and in the real build validates the GrpcService; it fails for unsupported specifiers (e.g. envoy_grpc), empty target_uri, or credential JSON it cannot parse.

Source

Thrown at internal/xds/httpfilter/extproc/ext_proc.go:130

		return nil, fmt.Errorf("extproc: error parsing config %v: unknown type %T, want *anypb.Any", cfg, cfg)
	}
	msg := new(v3procfilterpb.ExternalProcessor)
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("extproc: failed to unmarshal config %v: %v", cfg, err)
	}
	if msg.GetProcessingMode() == nil {
		return nil, fmt.Errorf("extproc: missing processing_mode in config %v", cfg)
	}
	if err := validateBodyProcessingMode(msg.GetProcessingMode()); err != nil {
		return nil, err
	}

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

	mutationRules, err := httpfilter.HeaderMutationRulesFromProto(msg.GetMutationRules())
	if err != nil {
		return nil, err
	}

	var allowedHeaders, disallowedHeaders []matcher.StringMatcher
	if allowed := msg.GetForwardRules().GetAllowedHeaders(); allowed != nil {
		allowedHeaders, err = httpfilter.ConvertStringMatchers(allowed.GetPatterns())
		if err != nil {
			return nil, err
		}
	}

	if disallowed := msg.GetForwardRules().GetDisallowedHeaders(); disallowed != nil {
		disallowedHeaders, err = httpfilter.ConvertStringMatchers(disallowed.GetPatterns())
		if err != nil {

View on GitHub (pinned to 03255a9237)

Solutions

  1. Use google_grpc (GrpcService_GoogleGrpc) rather than envoy_grpc for the ext_proc grpc_service.
  2. Set a non-empty, dialable target_uri on google_grpc.
  3. Validate any channel_credentials/call_credentials JSON the parser must consume; simplify to insecure/plain creds to isolate the cause.
  4. Re-apply and confirm ACK.

Example fix

// before: envoy_grpc is not parseable
//   grpc_service: { envoy_grpc: { cluster_name: "ext-proc" } }
//
// after: google_grpc with a concrete target
//   grpc_service: { google_grpc: { target_uri: "dns:///ext-proc.ns:9092" } }
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the ext_proc grpc_service like the injected parser does
// (internal/internal.go:42, called at ext_proc.go:128).
func validateExtProcGrpcService(gs *v3corepb.GrpcService) error {
    if gs == nil {
        return fmt.Errorf("grpc_service is nil")
    }
    if gs.GetGoogleGrpc() == nil {
        return fmt.Errorf("expected non-nil GoogleGrpc")
    }
    if gs.GetGoogleGrpc().GetTargetUri() == "" {
        return fmt.Errorf("empty target_uri in GoogleGrpc")
    }
    return nil
}

Prevention

When it happens

Trigger: msg.GetGrpcService() is non-nil but iextproc.ParseGRPCServiceConfig at ext_proc.go:128 returns a non-nil error — e.g. envoy_grpc used instead of google_grpc, an empty target_uri, or malformed channel/call credentials JSON.

Common situations: Control plane emits grpc_service.envoy_grpc (cluster-based) which the gRPC-side parser rejects; google_grpc.target_uri is blank; credentials JSON is malformed or references an unsupported plugin.

Understand the failure class

Related errors


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