labstack/echo · critical
response writer flushing is not supported
Error message
response writer flushing is not supported
What it means
Panicked (not returned) by bodyDumpResponseWriter.Flush when the underlying http.ResponseWriter does not support flushing, as reported by http.NewResponseController(...).Flush() returning http.ErrNotSupported. The BodyDump wrapper proxies Flush to the real writer; if the real writer cannot flush, the middleware panics because flushing was explicitly requested (e.g. by a handler calling c.Response().Flush()).
Source
Thrown at middleware/body_dump.go:157
config.Handler(c, reqBody, resBuf.Bytes(), err)
return err
}
}, nil
}
func (w *bodyDumpResponseWriter) WriteHeader(code int) {
w.ResponseWriter.WriteHeader(code)
}
func (w *bodyDumpResponseWriter) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}
func (w *bodyDumpResponseWriter) Flush() {
err := http.NewResponseController(w.ResponseWriter).Flush()
if err != nil && errors.Is(err, http.ErrNotSupported) {
panic(errors.New("response writer flushing is not supported"))
}
}
func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return http.NewResponseController(w.ResponseWriter).Hijack()
}
func (w *bodyDumpResponseWriter) Unwrap() http.ResponseWriter {
return w.ResponseWriter
}
var bodyDumpBufferPool = sync.Pool{
New: func() any {
return new(bytes.Buffer)
},
}
type limitedWriter struct {View on GitHub (pinned to 05489dc173)
Solutions
- Ensure the underlying ResponseWriter implements http.Flusher (httptest.ResponseRecorder does; wrap custom writers to forward Flush)
- Skip BodyDump middleware for streaming endpoints using the Skipper function
- Use a Recover middleware to catch the panic, though fixing the writer is the real solution
Example fix
// before — custom writer without Flush triggers panic
// when handler calls c.Response().Flush()
// after — implement Flush on your custom writer
type myWriter struct{ http.ResponseWriter }
func (w *myWriter) Flush() {
if f, ok := w.ResponseWriter.(http.Flusher); ok { f.Flush() }
} Defensive patterns
Strategy: fallback
Type guard
// Check if the response writer supports flushing
func canFlush(rw http.ResponseWriter) bool {
_, ok := rw.(http.Flusher)
return ok
} Try / catch
// Wrap with Recover middleware to catch the panic
e.Use(middleware.Recover())
e.Use(middleware.BodyDumpWithConfig(middleware.BodyDumpConfig{
Handler: dumpHandler,
Skipper: func(c echo.Context) bool {
// skip streaming endpoints that flush
return strings.HasPrefix(c.Path(), "/stream")
},
})) Prevention
- Ensure custom ResponseWriter wrappers forward Flush() via http.Flusher
- Use the Skipper to exclude streaming/SSE endpoints from BodyDump
- Always pair BodyDump with Recover middleware as a safety net
When it happens
Trigger: Using BodyDump middleware with a handler that calls c.Response().Flush() (SSE, streaming, chunked responses) when the underlying ResponseWriter does not implement http.Flusher. Happens in test setups with httptest.ResponseRecorder (which implements Flush) but can fail with custom writers or certain server configurations.
Common situations: Streaming/SSE handlers combined with BodyDump middleware in a test environment using a non-flushable mock ResponseWriter. Custom ResponseWriter wrappers that don't forward Flush.
Related errors
- echo body-dump middleware requires a handler function
- echo basic-auth middleware requires a validator function
- invalid gzip level
- timeout must be set
- at least one AllowOrigins is required or UnsafeAllowOriginFu
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/4ba0df75f38e93ec.json.
Report an issue: GitHub.