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
- Use the envoy.config.core.v3.GrpcService.grpc (EnvoyGrpc) variant with a valid target_uri in the override, not the google_grpc variant.
- Ensure target_uri is non-empty and resolvable (e.g. dns:///ext-proc.default.svc:443).
- Strip per-route grpc_service overrides you do not need and let the base config supply the server.
- 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
- Prefer envoy_grpc (EnvoyGrpc) over google_grpc for ext_proc grpc_service.
- Leave the per-route grpc_service unset when you can reuse the base config server.
- Keep a unit test that runs ParseFilterConfigOverride on every override template you publish.
- Document the supported credentials subset so authors do not send unsupported fields.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- extproc: failed to parse grpc_service
- extproc: failed to unmarshal override
- external processor returned invalid body mutation in body…
- external processor returned unexpected status
- external processor returned unexpected status
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)