grpc/grpc-go · error
extproc: invalid response trailer mode %v: must be %q when r
Error message
extproc: invalid response trailer mode %v: must be %q when response body mode is %q
What it means
Raised by validateBodyProcessingMode (ext_proc.go:104) when response_body_mode is GRPC but response_trailer_mode is not SEND. gRPC needs to send response trailers to the processor whenever it is processing the response body (so it can mark end-of-stream correctly); any other trailer mode in that combination is rejected.
Source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:104
func (builder) TypeURLs() []string {
return []string{
"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor",
"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExtProcPerRoute",
}
}
// validateBodyProcessingMode ensures that the body processing mode is either
// NONE or GRPC. Also ensures that if response body mode is GRPC then response
// trailer mode must be SEND.
func validateBodyProcessingMode(mode *v3procfilterpb.ProcessingMode) error {
if m := mode.GetRequestBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {
return fmt.Errorf("extproc: invalid request body mode %v: want %q or %q", m, "NONE", "GRPC")
}
if m := mode.GetResponseBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {
return fmt.Errorf("extproc: invalid response body mode %v: want %q or %q", m, "NONE", "GRPC")
}
if mode.GetResponseBodyMode() == v3procfilterpb.ProcessingMode_GRPC && mode.GetResponseTrailerMode() != v3procfilterpb.ProcessingMode_SEND {
return fmt.Errorf("extproc: invalid response trailer mode %v: must be %q when response body mode is %q", mode.GetResponseTrailerMode(), "SEND", "GRPC")
}
return nil
}
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, errView on GitHub (pinned to 03255a9237)
Solutions
- Set response_trailer_mode: SEND whenever response_body_mode is GRPC.
- If you do not want trailer processing, switch response_body_mode to NONE instead of leaving it GRPC with SKIP trailers.
- Re-apply the resource and confirm it is ACKed.
Example fix
// before
// processing_mode: { response_body_mode: GRPC, response_trailer_mode: SKIP } // -> error 374
//
// after
// processing_mode: { response_body_mode: GRPC, response_trailer_mode: SEND } Defensive patterns
Strategy: validation
Validate before calling
// Validate the response body/trailer coupling (ext_proc.go:103-105).
func validateResponseTrailerMode(pm *v3procfilterpb.ProcessingMode) error {
if pm.GetResponseBodyMode() == v3procfilterpb.ProcessingMode_GRPC && pm.GetResponseTrailerMode() != v3procfilterpb.ProcessingMode_SEND {
return fmt.Errorf("response_trailer_mode must be SEND when response_body_mode is GRPC")
}
return nil
} Prevention
- Whenever you set response_body_mode: GRPC, also set response_trailer_mode: SEND.
- If trailers must be skipped, use response_body_mode: NONE instead of GRPC+SKIP.
- Encode this coupling as a schema/CI rule for ext_proc processing_mode.
When it happens
Trigger: At ext_proc.go:103, mode.GetResponseBodyMode() == GRPC and mode.GetResponseTrailerMode() != SEND (e.g. it is SKIP or DEFAULT-resolved-to-skip).
Common situations: Config sets response_body_mode: GRPC for response mutation but explicitly sets response_trailer_mode: SKIP (or relies on the default skip) because trailers weren't wanted; partial config produced by only setting the body mode.
Related errors
- extproc: invalid request body mode %v: want %q or %q
- extproc: invalid response body mode %v: want %q or %q
- extproc: missing processing_mode in config %v
- extproc: error parsing config %v: unknown type %T, want *any
- extproc: failed to unmarshal config %v: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/efbc9324a71e3b6b.
Report an issue: GitHub.