grpc/grpc-go · error

external processor sent an immediate response but immediate…

Error message

external processor sent an immediate response but immediate responses are disabled in configuration

What it means

handleImmediateResponse (ext_proc.go:1742) fires when the external processor sends an immediate_response while config.disableImmediateResponse is true. The filter is configured to forbid immediate responses, so it fails the stream (or bypasses it per failureModeAllow) instead of honoring the abort.

Solutions

  1. If immediate responses are intended, remove disableImmediateResponse from the extproc filter config in the xDS Listener/Route.
  2. If immediate responses must stay disabled, fix the external processor to never send them (use header mutation + CONTINUE instead).
  3. Reconcile the control-plane config and server contract before redeploying.

Example fix

// before (xDS filter config)
disable_immediate_response: true

// after
// (field removed or set false) disable_immediate_response: false
Defensive patterns

Strategy: validation

Validate before calling

// Before deploying, reconcile filter config and server contract
if filterConfig.DisableImmediateResponse && serverSendsImmediateResponses {
    return errors.New("extproc: immediate responses disabled in config but server emits them")
}

Try / catch

// Client-side: surfaces as codes.Internal.
if st, ok := status.FromError(err); ok && strings.Contains(st.Message(), "immediate responses are disabled") {
    // remove disableImmediateResponse from config or stop sending immediate responses
}

Prevention

When it happens

Trigger: Client filter config sets disableImmediateResponse=true and the external processor returns a ProcessingResponse with the immediate_response variant set.

Common situations: Operator disabled immediate responses for safety/latency reasons, but the external processor still emits them (e.g., for auth rejection). Mismatch between control-plane filter config and server behavior.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/d735803f50196e5b. Report an issue: GitHub.

Appendix: source

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

	// external processor.
	outgoingMD, _ := metadata.FromOutgoingContext(ctx)
	if outgoingMD == nil {
		outgoingMD = metadata.MD{}
	}
	if err = cs.applyMutations(header.GetResponse().GetHeaderMutation(), outgoingMD); err != nil {
		cs.handleHeaderError(err, newStream, opts)
		return false
	}
	dataplaneCtx := metadata.NewOutgoingContext(ctx, outgoingMD)
	if err = cs.createDataplaneStream(dataplaneCtx, newStream, opts); err != nil {
		return false
	}
	return true
}

func (cs *clientStream) handleImmediateResponse(imm *v3procservicepb.ImmediateResponse, newStream func(context.Context, ...grpc.CallOption) (grpc.ClientStream, error), opts []grpc.CallOption) {
	if cs.config.disableImmediateResponse {
		err := fmt.Errorf("external processor sent an immediate response but immediate responses are disabled in configuration")
		if cs.dataplaneStream == nil {
			cs.handleHeaderError(err, newStream, opts)
		} else {
			cs.failProcStream(err)
		}
		return
	}

	statusCode := codes.Internal
	if imm.GetGrpcStatus() != nil {
		statusCode = codes.Code(imm.GetGrpcStatus().GetStatus())
		if statusCode > codes.Code(16) {
			statusCode = codes.Unknown
		}
	}
	err := status.Error(statusCode, imm.GetDetails())

	if cs.trailerSent.Load() {

View on GitHub (pinned to 0c51461d27)