grpc/grpc-go · error
extproc: incorrect config type provided (%T): %v
Error message
extproc: incorrect config type provided (%T): %v
What it means
Raised by BuildClientInterceptor when the base filter config handed to it is not the internal baseConfig type produced by ParseFilterConfig. The builder pipeline guarantees that ParseFilterConfig returns a baseConfig; any other concrete type indicates the httpfilter framework handed back an unexpected value.
Source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:238
return &clientFilter{
metricsRecorder: opts.MetricsRecorder,
target: opts.Target,
}
}
var _ httpfilter.ClientFilterBuilder = builder{}
type clientFilter struct {
metricsRecorder estats.MetricsRecorder
target string
}
func (clientFilter) Close() {}
func (cf *clientFilter) BuildClientInterceptor(base, override httpfilter.FilterConfig) (httpfilter.ClientInterceptor, error) {
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{View on GitHub (pinned to 03255a9237)
Solutions
- Ensure base originates from extproc's ParseFilterConfig (returns baseConfig) and not from another filter's builder.
- In tests, pass a real baseConfig value rather than a mock FilterConfig.
- Check for TypeURL collisions in the httpfilter registry and that the extproc builder is the one handling type type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor.
Example fix
// before (test): wrong base type
cf := clientFilter{}
cf.BuildClientInterceptor(mockConfig{}, nil)
// after
cf := clientFilter{}
cf.BuildClientInterceptor(baseConfig{server: srv, processingModes: pm}, nil) Defensive patterns
Strategy: type-guard
Validate before calling
// In tests, assert the base config is the extproc baseConfig.
func mustBuild(cf httpfilter.ClientFilter, base, ov httpfilter.FilterConfig) (httpfilter.ClientInterceptor, error) {
if _, ok := base.(baseConfig); !ok {
return nil, fmt.Errorf("base not extproc baseConfig: %T", base)
}
return cf.BuildClientInterceptor(base, ov)
} Type guard
func isBaseConfig(c httpfilter.FilterConfig) bool { _, ok := c.(baseConfig); return ok } Prevention
- Always source base config from extproc's ParseFilterConfig.
- Avoid registering two builders under the same TypeURL.
When it happens
Trigger: BuildClientInterceptor is invoked with a base FilterConfig produced by a different filter's ParseFilterConfig (registry/type-URL collision), or a test constructs a clientFilter and calls BuildClientInterceptor with an arbitrary httpfilter.FilterConfig value.
Common situations: Two filters registered under overlapping TypeURLs. A test that fakes base config with a struct that does not equal baseConfig. A refactor of baseConfig that left an old type still being passed.
Related errors
- extproc: incorrect override config type provided (%T): %v
- extproc: error parsing override %v: unknown type %T, want *a
- extproc: failed to unmarshal override %v: %v
- extproc: failed to parse grpc_service: %v
- extproc: response message does not implement proto.Message
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/7dc3fba88344fb4b.
Report an issue: GitHub.