panjf2000/ants · warning
operation timed out
Error message
operation timed out
What it means
ErrTimeout is returned by pool.ReleaseTimeout when the graceful release does not complete before the given timeout. ReleaseTimeout wraps ReleaseContext with a context deadline; if the context expires with context.DeadlineExceeded, it is converted to this sentinel (ants.go:422). It means in-flight workers had not finished within the budget.
Source
Thrown at ants.go:79
var (
// ErrLackPoolFunc will be returned when invokers don't provide function for pool.
ErrLackPoolFunc = errors.New("must provide function for pool")
// ErrInvalidPoolExpiry will be returned when setting a negative number as the periodic duration to purge goroutines.
ErrInvalidPoolExpiry = errors.New("invalid expiry for pool")
// ErrPoolClosed will be returned when submitting task to a closed pool.
ErrPoolClosed = errors.New("this pool has been closed")
// ErrPoolOverload will be returned when the pool is full and no workers available.
ErrPoolOverload = errors.New("too many goroutines blocked on submit or Nonblocking is set")
// ErrInvalidPreAllocSize will be returned when trying to set up a negative capacity under PreAlloc mode.
ErrInvalidPreAllocSize = errors.New("can not set up a negative capacity under PreAlloc mode")
// ErrTimeout will be returned after the operations timed out.
ErrTimeout = errors.New("operation timed out")
// ErrInvalidPoolIndex will be returned when trying to retrieve a pool with an invalid index.
ErrInvalidPoolIndex = errors.New("invalid pool index")
// ErrInvalidLoadBalancingStrategy will be returned when trying to create a MultiPool with an invalid load-balancing strategy.
ErrInvalidLoadBalancingStrategy = errors.New("invalid load-balancing strategy")
// ErrInvalidMultiPoolSize will be returned when trying to create a MultiPool with an invalid size.
ErrInvalidMultiPoolSize = errors.New("invalid size for multiple pool")
// workerChanCap determines whether the channel of a worker should be a buffered channel
// to get the best performance. Inspired by fasthttp at
// https://github.com/valyala/fasthttp/blob/master/workerpool.go#L139
workerChanCap = func() int {
// Use blocking channel if GOMAXPROCS=1.
// This switches context from sender to receiver immediately,
// which results in higher performance (under go1.5 at least).
if runtime.GOMAXPROCS(0) == 1 {View on GitHub (pinned to 107e376781)
Solutions
- Increase the timeout passed to ReleaseTimeout to cover worst-case task duration.
- On ErrTimeout, log the incomplete drain and proceed with forced shutdown (or call Release to force close).
- Split long tasks into smaller units or support cancellation via task arguments/context so they finish faster.
- Stop producers before draining so no new tasks extend the shutdown window.
Example fix
// before
if err := pool.ReleaseTimeout(time.Second); err != nil {
panic(err)
}
// after
if errors.Is(err, ants.ErrTimeout) {
log.Warn("pool drain timed out; forcing release")
pool.Release()
} Defensive patterns
Strategy: try-catch
Try / catch
err := pool.ReleaseTimeout(30 * time.Second)
if errors.Is(err, ants.ErrTimeout) {
log.Warn("drain timed out; forcing release")
pool.Release()
} Prevention
- Size the drain timeout to exceed worst-case task duration.
- Stop producers before draining.
- Make tasks context-aware so they can finish early during shutdown.
When it happens
Trigger: pool.ReleaseTimeout(d) where d elapses while long-running tasks still occupy workers, so pending task submission times out.
Common situations: Shutdown sequences with short drain windows while tasks are long-running (e.g. long HTTP handlers, DB batches); forgetting that blocked Submit waits until a worker is free.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- this pool has been closed
- too many goroutines blocked on submit or Nonblocking is set
- pool %d: %v
- must provide function for pool
- invalid expiry for pool
AI-assisted analysis of panjf2000/ants@107e376781 (2026-09-06).
Data as JSON: /api/errors/43cb6e366474ab35.
Report an issue: GitHub.