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 ParseFilterConfigOverride when the per-route override declares a grpc_service but iextproc.ParseGRPCServiceConfig rejects it. The GrpcService sub-message is structurally invalid or references a target the resolver cannot make sense of, so the override's custom server cannot be used.

Source

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

	msg := new(v3procfilterpb.ExtProcPerRoute)
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("extproc: failed to unmarshal override %v: %v", ov, err)
	}
	override := msg.GetOverrides()

	var processingModesOpt optional.Optional[processingModes]
	if pm := override.GetProcessingMode(); pm != nil {
		if err := validateBodyProcessingMode(pm); err != nil {
			return nil, err
		}
		processingModesOpt = optional.New(processingModesFromProto(pm))
	}

	var serverOpt optional.Optional[xdsresource.GRPCServiceConfig]
	if override.GetGrpcService() != nil {
		server, err := iextproc.ParseGRPCServiceConfig(override.GetGrpcService())
		if err != nil {
			return nil, fmt.Errorf("extproc: failed to parse grpc_service: %v", err)
		}
		serverOpt = optional.New(server)
	}

	var failureModeAllowOpt optional.Optional[bool]
	if override.GetFailureModeAllow() != nil {
		failureModeAllowOpt = optional.New(override.GetFailureModeAllow().GetValue())
	}

	return overrideConfig{
		server:             serverOpt,
		processingModes:    processingModesOpt,
		failureModeAllow:   failureModeAllowOpt,
		requestAttributes:  override.GetRequestAttributes(),
		responseAttributes: override.GetResponseAttributes(),
	}, nil
}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Inspect the wrapped error from ParseGRPCServiceConfig (it is printed via %v) to see exactly which GrpcService field is rejected.
  2. Provide a complete grpc_service with either envoy_grpc.target_uri or google_grpc.target_uri set to a resolvable authority (e.g. dns:///ext-proc.ns:8080).
  3. If using a per-route server, validate the same GrpcService payload in the control plane before publishing the LDS resource.

Example fix

// before: override grpc_service has empty target
overrides:
  grpc_service:
    envoy_grpc: {}

// after
overrides:
  grpc_service:
    envoy_grpc:
      cluster_name: ext_proc_cluster
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the grpc_service before publishing / before trusting an override.
func validateGrpcService(gs *v3corepb.GrpcService) error {
    if gs == nil { return fmt.Errorf("grpc_service is nil") }
    if eg := gs.GetEnvoyGrpc(); eg != nil && eg.GetClusterName() == "" {
        return fmt.Errorf("envoy_grpc.cluster_name is empty")
    }
    if gg := gs.GetGoogleGrpc(); gg != nil && gg.GetTargetUri() == "" {
        return fmt.Errorf("google_grpc.target_uri is empty")
    }
    return nil
}

Prevention

When it happens

Trigger: ExtProcPerRoute.overrides.grpc_service is set but malformed — missing both envoy_grpc and google_grpc, an unparseable target_uri, or a google_grpc with an invalid stat_prefix/config. ParseGRPCServiceConfig returns a non-nil error which is wrapped here.

Common situations: Operator adds a per-route override pointing the filter at a different ext-proc server but forgets the target_uri or uses a malformed URI scheme. A typo in the grpc_service protobuf. The xdsclient's GrpcService parser rejecting a google_grpc sub-field after a library upgrade.

Understand the failure class

Related errors


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