grpc/grpc-go · error

extproc: incorrect override config type provided (%T): %v

Error message

extproc: incorrect override config type provided (%T): %v

What it means

Raised by BuildClientInterceptor when a per-route override config is present but is not the overrideConfig type produced by ParseFilterConfigOverride. Mirrors the base-config invariant: the override must be an overrideConfig or nil.

Source

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

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{
		config:          config,
		procClient:      v3procservicegrpc.NewExternalProcessorClient(cc),
		closeClient:     cancel,
		metricsRecorder: cf.metricsRecorder,
		target:          cf.target,
	}, nil
}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Ensure the override, when non-nil, comes from extproc's ParseFilterConfigOverride (returns overrideConfig).
  2. In tests, pass either nil or a real overrideConfig value.
  3. Resolve any TypeURL collision so the extproc ExtProcPerRoute URL is handled only by the extproc builder.

Example fix

// before (test): arbitrary override
cf.BuildClientInterceptor(base, wrongOverride{})

// after
cf.BuildClientInterceptor(base, overrideConfig{})  // or nil
Defensive patterns

Strategy: type-guard

Validate before calling

func isOverrideConfig(c httpfilter.FilterConfig) bool { _, ok := c.(overrideConfig); return ok }

Type guard

func isOverrideConfig(c httpfilter.FilterConfig) bool { _, ok := c.(overrideConfig); return ok }

Prevention

When it happens

Trigger: BuildClientInterceptor is called with a non-nil override whose concrete type is not overrideConfig — typically a registry/type-URL collision dispatching the override through the wrong builder, or a test passing a hand-rolled FilterConfig.

Common situations: Override produced by a different filter's ParseFilterConfigOverride due to overlapping TypeURLs. Tests that build a clientInterceptor with an arbitrary override struct. A refactor where overrideConfig changed but a stale producer remains.

Related errors


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