When Request.Body.Close Started Returning io.EOF

While testing an internal HTTP service against Go 1.27, a handler that had worked for years started reporting errors from an unlikely place: r.Body.Close(). The handler does what any length-aware decoder does — it reads exactly the payload it expects and stops, without reading far enough to observe io.EOF. Then it closes the body. On Go 1.26 that Close returned nil. On 1.27 it returns io.EOF. Pinning it down Timer-driven HTTP repros are flaky, so I drove net/http over a net.Pipe with a one-shot listener: fully deterministic, no real sockets, no timeouts. The whole thing fits in a playground link. A handler reads 2 of 4 body bytes, closes, and reports the error: ...

August 20, 2026 · 2 min · Moises Vega