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
The extproc filter can be configured to disable immediate responses (disableImmediateResponse). If the server then sends a ProcessingResponse with an ImmediateResponse set, the filter cannot honor it and treats it as an error (ext_proc.go:1570), failing or bypassing the stream.
Source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:1571
// 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 03255a9237)
Solutions
- Align configuration and server behavior: either set disable_immediate_response=false in the extproc filter config, or stop the server from sending ImmediateResponse messages.
- Roll the extproc server to a version that respects the negotiated 'no immediate responses' contract.
- While migrating, set failure_mode_allow=true to avoid failing RPCs.
Example fix
// before: config disables immediate responses, server sends one
filterConfig.DisableImmediateResponse = true
// server: stream.Send(&procservicepb.ProcessingResponse{Response: &procservicepb.ProcessingResponse_ImmediateResponse{...}})
// after: allow immediate responses, or have the server avoid them
filterConfig.DisableImmediateResponse = false Defensive patterns
Strategy: validation
Validate before calling
// Before enabling the filter, ensure config and server agree on immediate responses
if serverMaySendImmediateResponse {
filterConfig.DisableImmediateResponse = false
} Prevention
- Keep disable_immediate_response consistent with the deployed extproc server's behavior.
- Set failure_mode_allow during migration periods.
- Document the contract in your filter config so operators don't flip the flag blindly.
When it happens
Trigger: xDS extproc config sets disable_immediate_response = true, and the external processor sends a ProcessingResponse whose immediate_response field is populated.
Common situations: Operator enabled disable_immediate_response for safety/forward-compat while the deployed server still emits immediate responses; mismatch between the negotiated contract and server behavior; copy-pasted filter config from another environment.
Related errors
- external processor unexpectedly sent duplicate response trai
- external processor returned unexpected status %v for body re
- external processor returned invalid body mutation in body re
- external processor returned compressed grpc message which is
- external processor returned an unexpected message type %T, e
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/d735803f50196e5b.
Report an issue: GitHub.