grpc/grpc-go · error

extproc: empty grpc_service provided in config %v

Error message

extproc: empty grpc_service provided in config %v

What it means

Raised by ParseFilterConfig (ext_proc.go:126) when the ExternalProcessor config unmarshals and has a processing_mode but no grpc_service. ext_proc needs a backend gRPC stream to the external processor; without a grpc_service the filter cannot operate, so the resource is rejected.

Source

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

func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
	m, ok := cfg.(*anypb.Any)
	if !ok {
		return nil, fmt.Errorf("extproc: error parsing config %v: unknown type %T, want *anypb.Any", cfg, cfg)
	}
	msg := new(v3procfilterpb.ExternalProcessor)
	if err := m.UnmarshalTo(msg); err != nil {
		return nil, fmt.Errorf("extproc: failed to unmarshal config %v: %v", cfg, err)
	}
	if msg.GetProcessingMode() == nil {
		return nil, fmt.Errorf("extproc: missing processing_mode in config %v", cfg)
	}
	if err := validateBodyProcessingMode(msg.GetProcessingMode()); err != nil {
		return nil, err
	}

	if msg.GetGrpcService() == nil {
		return nil, fmt.Errorf("extproc: empty grpc_service provided in config %v", cfg)
	}
	server, err := iextproc.ParseGRPCServiceConfig(msg.GetGrpcService())
	if err != nil {
		return nil, fmt.Errorf("extproc: failed to parse grpc_service %v", err)
	}

	mutationRules, err := httpfilter.HeaderMutationRulesFromProto(msg.GetMutationRules())
	if err != nil {
		return nil, err
	}

	var allowedHeaders, disallowedHeaders []matcher.StringMatcher
	if allowed := msg.GetForwardRules().GetAllowedHeaders(); allowed != nil {
		allowedHeaders, err = httpfilter.ConvertStringMatchers(allowed.GetPatterns())
		if err != nil {
			return nil, err
		}
	}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Add a grpc_service block (google_grpc with a non-empty target_uri) to the ExternalProcessor config.
  2. Ensure the same grpc_service parses cleanly (google_grpc, concrete target) so you do not then hit error 379.
  3. Re-apply the LDS resource and verify the client ACKs it.

Example fix

// before
//   external_processor: { processing_mode: { ... } }   // grpc_service missing -> error 378
//
// after
//   external_processor: {
//     grpc_service: { google_grpc: { target_uri: "dns:///ext-proc.ns:9092" } },
//     processing_mode: { ... }
//   }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure grpc_service is present (ext_proc.go:125-127).
func ensureExtProcGrpcService(cfg *v3procfilterpb.ExternalProcessor) error {
    if cfg.GetGrpcService() == nil {
        return fmt.Errorf("extproc: grpc_service is required")
    }
    return nil
}

Prevention

When it happens

Trigger: msg.GetGrpcService() == nil at ext_proc.go:125, i.e. the ExternalProcessor proto was provided with a processing_mode but the grpc_service field was not set.

Common situations: A config that defines processing_mode but forgets grpc_service; a templating condition that drops the grpc_service block; partial config during rollout.

Related errors


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