panjf2000/ants · warning

too many goroutines blocked on submit or Nonblocking is set

Error message

too many goroutines blocked on submit or Nonblocking is set

What it means

ErrPoolOverload is returned by retrieveWorker (ants.go:534) when a task cannot be enqueued because the pool is at capacity and the caller opted out of blocking: either Nonblocking is set, or MaxBlockingTasks is non-zero and the number of already-waiting submissions has reached that limit. It is a back-pressure signal, not a crash.

Source

Thrown at ants.go:73

	// OPENED represents that the pool is opened.
	OPENED = iota

	// CLOSED represents that the pool is closed.
	CLOSED
)

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

View on GitHub (pinned to 107e376781)

Solutions

  1. Handle the error at the call site: drop, defer, or requeue the task (this is the intended use in nonblocking mode).
  2. Increase pool capacity (raise size in NewPool or adjust options) to match producer throughput.
  3. Raise/remove MaxBlockingTasks to allow more submissions to queue, or remove WithNonblocking to let Submit block.
  4. Add retry with backoff if tasks must not be lost.

Example fix

// before
if err := pool.Submit(task); err != nil {
    panic(err)
}
// after
if errors.Is(err, ants.ErrPoolOverload) {
    metrics.Inc("pool_overload")
    go func() { _ = queue.PushBack(task) }() // shed/load-shape instead of panic
}
Defensive patterns

Strategy: retry

Validate before calling

if pool.Cap() > 0 && pool.Waiting() >= maxBlockingTasks && !blockingAllowed {
    // shed or requeue before calling Submit
}

Try / catch

err := pool.Submit(task)
if errors.Is(err, ants.ErrPoolOverload) {
    metrics.Inc("pool_overload")
    time.AfterFunc(backoff, func() { _ = pool.Submit(task) })
}

Prevention

When it happens

Trigger: pool.Submit on a full pool created with ants.WithNonblocking(true); or with WithMaxBlockingTasks(n) when p.Waiting() >= n and no worker is free.

Common situations: Producers outpacing workers during traffic spikes; misconfigured MaxBlockingTasks lower than burst concurrency; deliberately using nonblocking mode for load shedding.

Related errors


AI-assisted analysis of panjf2000/ants@107e376781 (2026-09-06). Data as JSON: /api/errors/1eaff3d26805e127. Report an issue: GitHub.