grpc/grpc-go · error
external processor returned compressed grpc message which is
Error message
external processor returned compressed grpc message which is not supported
What it means
grpc-go's extproc filter does not support receiving gRPC messages that are marked compressed by the external processor (ext_proc.go:1366). The StreamedBodyResponse.grpc_message_compressed flag must be false; otherwise the filter fails the stream because it cannot handle a compressed payload in this code path.
Source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:1367
// Signal that the response trailer is modified and ready to be sent to
// the client.
cs.fireResponseTrailerReady()
}
}
}
func (cs *clientStream) validateBodyResponse(bodyResp *v3procservicepb.BodyResponse) (*v3procservicepb.StreamedBodyResponse, bool) {
if status := bodyResp.GetResponse().GetStatus(); status != v3procservicepb.CommonResponse_CONTINUE {
cs.failProcStream(fmt.Errorf("external processor returned unexpected status %v for body response, expected %v", status, v3procservicepb.CommonResponse_CONTINUE))
return nil, false
}
streamedResp := bodyResp.GetResponse().GetBodyMutation().GetStreamedResponse()
if streamedResp == nil {
cs.failProcStream(fmt.Errorf("external processor returned invalid body mutation in body response"))
return nil, false
}
if streamedResp.GetGrpcMessageCompressed() {
cs.failProcStream(fmt.Errorf("external processor returned compressed grpc message which is not supported"))
return nil, false
}
return streamedResp, true
}
func (cs *clientStream) applyMutations(mutation *v3procservicepb.HeaderMutation, md metadata.MD) error {
if mutation == nil {
return nil
}
if err := cs.config.mutationRules.ApplyAdditions(mutation.GetSetHeaders(), md); err != nil {
return err
}
return cs.config.mutationRules.ApplyRemovals(mutation.GetRemoveHeaders(), md)
}
// closeProcSend gracefully half-closes the external processor stream across the
// background send goroutine by pushing a nil sentinel onto procSendCh.
func (cs *clientStream) closeProcSend() {View on GitHub (pinned to 03255a9237)
Solutions
- Set grpc_message_compressed = false on all StreamedBodyResponse messages from the extproc server.
- Decompress the chunk before placing it in StreamedBodyResponse so the flag can stay false.
- If compression is required end-to-end, configure it at the gRPC channel/compression level, not via the extproc flag.
Example fix
// before streamedResp.GrpcMessageCompressed = true // after streamedResp.GrpcMessageCompressed = false
Defensive patterns
Strategy: validation
Validate before calling
// Server side: clear the flag before sending
if streamedResp.GetGrpcMessageCompressed() {
streamedResp.GrpcMessageCompressed = false
} Prevention
- grpc-go does not accept compressed gRPC messages from extproc; keep the flag false.
- Decompress chunks server-side if you need to inspect them.
- Configure compression at the channel level, not via the extproc flag.
When it happens
Trigger: The extproc server sets StreamedBodyResponse.grpc_message_compressed = true on a body response.
Common situations: Server copies a compressed response directly into the chunk and flags it compressed; misunderstanding the contract where the extproc layer is expected to deliver uncompressed chunks for grpc-go to (re)compress itself.
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 an unexpected message type %T, e
- external processor returned unexpected status %v for request
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/6de6bbfff7240dff.
Report an issue: GitHub.