io.ErrClosedPipe
GoERRORNotableIO

io: read/write on closed pipe

Quick Answer

Close the PipeWriter only after the PipeReader has finished consuming all data.

What this means

Returned when reading from or writing to an io.Pipe after either end has been closed. Indicates a producer/consumer lifecycle mismatch.

Why it happens
  1. 1PipeWriter closed before PipeReader finishes reading
  2. 2Goroutine writing to a pipe whose reader has already exited

Fix

Coordinate close with done channel

Coordinate close with done channel
done := make(chan struct{})
go func() { io.Copy(dst, pr); close(done) }()
pw.Close()
<-done

Why this works

Waiting on done ensures the reader drains before the writer signals completion.

Code examples
Detectgo
_, err := pw.Write(data)
if errors.Is(err, io.ErrClosedPipe) {
    fmt.Println("pipe closed")
}
Basic pipego
pr, pw := io.Pipe()
go func() { pw.Write([]byte("hi")); pw.Close() }()
io.Copy(os.Stdout, pr)
CloseWithErrorgo
pw.CloseWithError(fmt.Errorf("abort"))
// reader receives the custom error
Sources
Official documentation ↗

Go standard library

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Go errors