grpc/grpc-go · critical
extproc: failed to create channel to the external processor
Error message
extproc: failed to create channel to the external processor server %q: %v
What it means
Raised by BuildClientInterceptor when iextproc.CreateExtProcChannel(config.server) fails. The filter could not establish a gRPC client channel to the configured external processor server (the dial failed before any RPC), so the interceptor cannot be built and the filter is rejected for that target.
Source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:254
b, ok := base.(baseConfig)
if !ok {
return nil, fmt.Errorf("extproc: incorrect config type provided (%T): %v", base, base)
}
var ov overrideConfig
if override != nil {
ov, ok = override.(overrideConfig)
if !ok {
return nil, fmt.Errorf("extproc: incorrect override config type provided (%T): %v", override, override)
}
}
config := newInterceptorConfig(b, ov)
// Create a channel to the external processor server.
cc, cancel, err := iextproc.CreateExtProcChannel(config.server)
if err != nil {
return nil, fmt.Errorf("extproc: failed to create channel to the external processor server %q: %v", config.server.TargetURI, err)
}
return &clientInterceptor{
config: config,
procClient: v3procservicegrpc.NewExternalProcessorClient(cc),
closeClient: cancel,
metricsRecorder: cf.metricsRecorder,
target: cf.target,
}, nil
}
type clientInterceptor struct {
config baseConfig
procClient v3procservicegrpc.ExternalProcessorClient
closeClient func() error
metricsRecorder estats.MetricsRecorder
target string
}
View on GitHub (pinned to 03255a9237)
Solutions
- Check the wrapped dial error (%v) — it distinguishes DNS failure, TLS failure, and connection refused.
- Verify config.server.TargetURI resolves and the ext-proc server is reachable (grpcurl / kubectl port-forward / telnet to the port).
- Fix TLS: ensure the CA bundle and SNI/override match the server certificate, or switch to plaintext for debugging.
- If transient, ensure the channel factory has retry/backoff and the LDS update is reprocessed once endpoints come back.
Example fix
// before: unreachable target
grpc_service:
envoy_grpc:
cluster_name: ext_proc_cluster # cluster has 0 healthy endpoints
// after: target resolves to a live ext-proc server
grpc_service:
envoy_grpc:
cluster_name: ext_proc_cluster # cluster backs a healthy Service+Deployment Defensive patterns
Strategy: retry
Try / catch
// Channel/dial failures surface from BuildClientInterceptor as a wrapped error;
// retry by reprocessing the LDS resource once endpoints/TLS are fixed.
ci, err := cf.BuildClientInterceptor(base, ov)
if err != nil {
if strings.Contains(err.Error(), "failed to create channel to the external processor server") {
// transient: surface to xdsclient to retry on next update
}
return err
} Prevention
- Keep the ext_proc cluster healthy (readiness probes, enough replicas).
- Validate TLS CA/SNI against the server certificate before publishing LDS.
- Use a resolvable target_uri scheme (dns:///, xds:///) supported by the client.
When it happens
Trigger: Dialing config.server.TargetURI fails: DNS resolution error, no route to host, TLS handshake/cert verification failure, bad authority scheme, connection refused, or the channel factory rejecting the GRPCServiceConfig (e.g. invalid credentials).
Common situations: Ext-proc server pod is down or Service has no ready endpoints. TLS CA cert misconfigured or hostname mismatch. target_uri uses a scheme the resolver does not understand. Network policy/firewall blocking the port. Service mesh sidecar not injected so the authority is unreachable.
Related errors
- last connection error: %v
- failed to create a stream to external processor: %v
- failed to send client headers to external processor server:
- grpc: timed out when dialing
- pemfile: certificate and key file must be in the same direct
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/79a73044db67cfe4.
Report an issue: GitHub.