valyala/fasthttp · error

pipeline connection has been stopped

Error message

pipeline connection has been stopped

What it means

errPipelineConnStopped is an internal error returned by a PipelineClient's per-connection worker when the connection has been stopped (client closed or connection reset). Any request whose response channel was waiting is completed with this error. It means the pipeline connection was torn down while work was in flight.

Source

Thrown at client.go:3333

	n := 0
	for _, cc := range c.connClients {
		n += cc.PendingRequests()
	}
	c.connClientsLock.Unlock()
	return n
}

func (c *pipelineConnClient) PendingRequests() int {
	chs := c.acquirePipelineConnChannels()
	defer c.releasePipelineConnChannels(chs)

	c.chLock.Lock()
	n := len(chs.chR) + len(chs.chW)
	c.chLock.Unlock()
	return n
}

var errPipelineConnStopped = errors.New("pipeline connection has been stopped")

var DefaultTransport RoundTripper = &transport{}

type transport struct{}

// clientStreamBody serializes reads and keeps pooled response resources alive
// until an in-flight Read has returned. interrupt must unblock network reads
// without releasing the connection wrapper or reader pools; release performs
// that cleanup afterward.
type clientStreamBody struct {
	reader    io.Reader
	interrupt func()
	release   func(bool)
	closed    atomic.Bool
	fullyRead bool
	readLock  sync.Mutex
	closeOnce sync.Once
}

View on GitHub (pinned to c96f600972)

Solutions

  1. Ensure PipelineClient.Stop() is called only after all in-flight Do* calls finish (use WaitGroup)
  2. Retry the request on a fresh PipelineClient when this error is received
  3. Check server logs for connection resets / idle timeouts that kill the pipeline connection
  4. Handle this error explicitly in shutdown code instead of treating it as fatal

Example fix

// before
go func() { client.Do(req, resp) }()
client.Stop()
// after
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done(); client.Do(req, resp) }()
wg.Wait()
client.Stop()
Defensive patterns

Strategy: try-catch

Type guard

func isPipelineStopped(err error) bool {
    return errors.Is(err, fasthttp.ErrPipelineOverflow) || err != nil && strings.Contains(err.Error(), "pipeline connection has been stopped")
}

Try / catch

if err := pc.Do(req, resp); err != nil && isPipelineStopped(err) {
    pc = newPipelineClient() // recreate after Stop
}

Prevention

When it happens

Trigger: Calling PipelineClient.Do* concurrently with PipelineClient.Stop(), or after Stop(); the internal pipeline goroutine exiting (server closed the connection) while requests are still queued in chs.chR/chs.chW.

Common situations: Application shutting down a PipelineClient while background goroutines still issue requests; server dropping keep-alive pipeline connections mid-flight; race between Stop() and in-flight Do() calls.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/1c194ef0155247e1. Report an issue: GitHub.