go-redis/redis · info

connection marked for handoff with state

Error message

connection marked for handoff with state

What it means

Returned by PoolHook.OnGet (pool_hook.go:127) when a pooled connection has ShouldHandoff() == true — it received a MOVING notification and is awaiting relocation, so it must not be handed out for new commands. Like error 50 this is flow control: the pool skips it and selects another connection.

Solutions

  1. Raise PoolSize so marked connections don't starve the usable set.
  2. Ensure the handoff worker pool (MaxWorkers) drains marked connections promptly — increase it under heavy migration load.
  3. Treat this sentinel in any custom pool/errgroup wrapper as 'try another connection', not a fatal error.
  4. Verify HandoffQueueSize is large enough that marked connections are queued quickly rather than lingering.
Defensive patterns

Strategy: retry

Try / catch

// Pool internally retries with another connection. If exposed, retry:
if errors.Is(err, maintnotifications.ErrConnectionMarkedForHandoffWithState) {
    return retryCommand(ctx, cmd)
}

Prevention

When it happens

Trigger: A connection received a MOVING push notification (state set to moving/handoff-pending) but has not yet been queued/processed by a worker; OnGet sees ShouldHandoff() and returns (false, ErrConnectionMarkedForHandoffWithState) so the connection is reserved for handoff rather than reused.

Common situations: Normal during migrations — many connections may be marked simultaneously. Becomes visible as a hard error only if the pool is exhausted of unmarked connections (very small PoolSize relative to active handoffs).

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /api/errors/153dda5e603cee03. Report an issue: GitHub.

Appendix: source

Thrown at maintnotifications/errors.go:51

var (
	// ErrHandoffQueueFull is returned when the handoff queue is full
	ErrHandoffQueueFull = errors.New(logs.HandoffQueueFullError())
)

// Notification errors
var (
	// ErrInvalidNotification is returned when a notification is in an invalid format
	ErrInvalidNotification = errors.New(logs.InvalidNotificationError())
)

// connection handoff errors
var (
	// ErrConnectionMarkedForHandoff is returned when a connection is marked for handoff
	// and should not be used until the handoff is complete
	ErrConnectionMarkedForHandoff = errors.New(logs.ConnectionMarkedForHandoffErrorMessage)
	// ErrConnectionMarkedForHandoffWithState is returned when a connection is marked for handoff
	// and should not be used until the handoff is complete
	ErrConnectionMarkedForHandoffWithState = errors.New(logs.ConnectionMarkedForHandoffErrorMessage + " with state")
	// ErrConnectionInvalidHandoffState is returned when a connection is in an invalid state for handoff
	ErrConnectionInvalidHandoffState = errors.New(logs.ConnectionInvalidHandoffStateErrorMessage)
)

// shutdown errors
var (
	// ErrShutdown is returned when the maintnotifications manager is shutdown
	ErrShutdown = errors.New(logs.ShutdownError())
)

// circuit breaker errors
var (
	// ErrCircuitBreakerOpen is returned when the circuit breaker is open
	ErrCircuitBreakerOpen = errors.New(logs.CircuitBreakerOpenErrorMessage)
)

// circuit breaker configuration errors
var (

View on GitHub (pinned to 36d97525cd)