go-redis/redis · error
redis: autopipeline: no batch permit within the internal bac
Error message
redis: autopipeline: no batch permit within the internal backstop (engine overloaded or a batch is wedged)
What it means
Error "redis: autopipeline: no batch permit within the internal backstop (engine overloaded or a batch is wedged)" thrown in go-redis/redis.
Source
Thrown at autopipeline.go:1360
// EXPERIMENTAL: this API is subject to change, use with caution.
var ErrSubmitBlockingFace = errors.New(
"redis: Submit requires the deferred autopipeliner (AsyncAutoPipeline); on the blocking face use the typed methods or Do")
// errZeroAutoFuture is returned by Wait/WaitContext on a zero AutoFuture.
var errZeroAutoFuture = errors.New("redis: Wait on a zero AutoFuture")
// errDoNoArgs is returned by Do when called without a command.
var errDoNoArgs = errors.New("redis: AutoPipeliner.Do requires at least one argument")
// ErrAutoPipelineTimeout is set on drained commands when a flush could not
// obtain a batch permit within the engine's internal backstop — the engine is
// overloaded or an in-flight batch is wedged (e.g. read timeouts disabled on
// a dead peer). It is deliberately NOT context.DeadlineExceeded: the caller's
// own context did not expire, and errors.Is(err, context.DeadlineExceeded)
// must not fire for an internal engine timeout.
//
// EXPERIMENTAL: this API is subject to change, use with caution.
var ErrAutoPipelineTimeout = errors.New(
"redis: autopipeline: no batch permit within the internal backstop (engine overloaded or a batch is wedged)")
// Submit queues a command without blocking and returns an AutoFuture; Wait on
// it when the result is needed. This is the explicit form for working with raw
// Cmders on the deferred (async) face, where the typed methods (Set, Get, ...)
// provide the same deferred behaviour returning the usual *XxxCmd. The
// command's own result accessors (Err/Val/Result) are safe to use instead of
// Wait — they block until the command has executed. Connection-hostile
// command names (SHUTDOWN, MONITOR, SELECT, AUTH, MULTI, SUBSCRIBE, CLIENT,
// ...) never ride a shared pipeline connection: they are diverted to a
// normal pooled connection with plain Client.Do semantics. On a BLOCKING
// autopipeliner Submit is rejected (the future's Wait returns an error): the
// blocking face's ordering relies on every caller waiting for each command
// before issuing the next, which Submit by design does not do.
func (ap *AutoPipeliner) Submit(ctx context.Context, cmd Cmder) AutoFuture {
if ap.blocking {
cmd.SetErr(ErrSubmitBlockingFace)
return AutoFuture{cmd: cmd, batch: completedBatch}View on GitHub (pinned to 36d97525cd)
Solutions
- Reduce batch submission pressure (lower MaxConcurrentBatches / submission rate) so permits are released before the backstop expires
- Investigate wedged batches: ensure no command blocks indefinitely (set ReadTimeout) so batch workers can complete and release permits
When it happens
Trigger: Thrown at autopipeline.go:1360 when the library encounters an invalid state.
Common situations: Monitor autopipeline saturation and alert before the internal backstop is hit; never retry Submit in a tight loop on this error.
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/04022ffae8875500.json.
Report an issue: GitHub.