grpc/grpc-go · error

extproc: failed to parse grpc_service

Error message

extproc: failed to parse grpc_service: %v

What it means

Returned by ParseFilterConfigOverride (ext_proc.go:196) when the override's grpc_service field cannot be parsed by iextproc.ParseGRPCServiceConfig. Only the override path is affected; the route is rejected because the per-route external-processor target is not usable.

Solutions

  1. Use the envoy.config.core.v3.GrpcService.grpc (EnvoyGrpc) variant with a valid target_uri in the override, not the google_grpc variant.
  2. Ensure target_uri is non-empty and resolvable (e.g. dns:///ext-proc.default.svc:443).
  3. Strip per-route grpc_service overrides you do not need and let the base config supply the server.
  4. Upgrade the client and control plane to a matching revision that supports the credentials/authority fields in use.

Example fix

// before: override uses GoogleGrpc which gRPC-Go ext_proc cannot parse
override.GrpcService = &corev3.GrpcService{
  TargetIdentifier: "ext-proc:443",
}

// after: use EnvoyGrpc with an explicit target
override.GrpcService = &corev3.GrpcService{
  TargetIdentifier: "envoy_grpc",
}
override.GrpcService.GetEnvoyGrpc().ClusterName = "ext_proc_cluster"
Defensive patterns

Strategy: validation

Validate before calling

// Validate the override grpc_service is parseable before publishing.
func validateOverrideGrpcService(gs *corev3.GrpcService) error {
    if gs == nil {
        return nil // override server is optional
    }
    if gs.GetEnvoyGrpc() == nil {
        return fmt.Errorf("override grpc_service must use envoy_grpc; google_grpc is not supported")
    }
    if gs.GetEnvoyGrpc().GetClusterName() == "" {
        return fmt.Errorf("override envoy_grpc.cluster_name is empty")
    }
    return nil
}

Try / catch

if _, err := builder{}.ParseFilterConfigOverride(overrideAny); err != nil {
    if strings.Contains(err.Error(), "failed to parse grpc_service") {
        // the per-route grpc_service is invalid; drop it and reuse the base server
    }
}

Prevention

When it happens

Trigger: Triggered when an ExtProcPerRoute override sets overrides.grpc_service (ext_proc.go:193) and the underlying ParseGRPCServiceConfig returns an error — e.g. a google_grpc payload (Envoy's GoogleGrpc) instead of the supported grpc (EnvoyGrpc), an unsupported credentials type, an empty target, or a malformed authority.

Common situations: Configuring a per-route override that points to a different ext_proc server than the base config but using Envoy's google_grpc variant, omitting the target_uri, using a credentials spec the client does not implement, or a control-plane version that emits a grpc_service shape the client cannot consume.

Understand the failure class

Related errors


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

Appendix: 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 0c51461d27)