go-redis/redis · error
max handoff retries reached
Error message
max handoff retries reached
What it means
Returned by performHandoffInternal (handoff_worker.go:407-412) when IncrementAndGetHandoffRetries exceeds Config.MaxHandoffRetries. Unlike other handoff errors this one is non-retryable (shouldRetry=false): the connection has failed to relocate to its new endpoint too many times and is removed from the pool rather than being queued again.
Source
Thrown at maintnotifications/errors.go:17
package maintnotifications import ( "errors" "github.com/redis/go-redis/v9/internal/maintnotifications/logs" ) // Configuration errors var ( ErrInvalidRelaxedTimeout = errors.New(logs.InvalidRelaxedTimeoutError()) ErrInvalidHandoffTimeout = errors.New(logs.InvalidHandoffTimeoutError()) ErrInvalidHandoffWorkers = errors.New(logs.InvalidHandoffWorkersError()) ErrInvalidHandoffQueueSize = errors.New(logs.InvalidHandoffQueueSizeError()) ErrInvalidPostHandoffRelaxedDuration = errors.New(logs.InvalidPostHandoffRelaxedDurationError()) ErrInvalidEndpointType = errors.New(logs.InvalidEndpointTypeError()) ErrInvalidMaintNotifications = errors.New(logs.InvalidMaintNotificationsError()) ErrMaxHandoffRetriesReached = errors.New(logs.MaxHandoffRetriesReachedError()) // Configuration validation errors // ErrInvalidHandoffRetries is returned when the number of handoff retries is invalid ErrInvalidHandoffRetries = errors.New(logs.InvalidHandoffRetriesError()) ) // Integration errors var ( // ErrInvalidClient is returned when the client does not support push notifications ErrInvalidClient = errors.New(logs.InvalidClientError()) ) // Handoff errors var ( // ErrHandoffQueueFull is returned when the handoff queue is full ErrHandoffQueueFull = errors.New(logs.HandoffQueueFullError())
View on GitHub (pinned to 36d97525cd)
Solutions
- Verify the new endpoint is reachable from the client host (telnet/curl the host:port the MOVING notification advertised).
- Check EndpointType: if the server returns an internal IP/FQDN the client cannot route to, switch to an external type or fix network/DNS.
- If the endpoint is genuinely flaky but recoverable, raise Config.MaxHandoffRetries (1-10) to give handoff more attempts.
- Increase HandoffTimeout so transient slow dials don't each burn a retry.
Example fix
// before cfg := maintnotifications.DefaultConfig() // MaxHandoffRetries: 3 // after cfg := maintnotifications.DefaultConfig() cfg.MaxHandoffRetries = 5 cfg.HandoffTimeout = 30 * time.Second cfg.EndpointType = maintnotifications.EndpointTypeExternalIP
Defensive patterns
Strategy: retry
Try / catch
if errors.Is(err, maintnotifications.ErrMaxHandoffRetriesReached) {
// connection was dropped; the next command will use a fresh pooled conn.
// Investigate endpoint reachability / EndpointType, then retry the command.
} Prevention
- Verify MOVING-advertised endpoints are routable from the client host.
- Pick the correct EndpointType for your network topology.
- Raise MaxHandoffRetries (1-10) for genuinely flaky-but-recoverable endpoints.
- Monitor handoff-failure logs (logs.HandoffFailed).
When it happens
Trigger: A connection receives a MOVING notification, is handed off, but the new endpoint is repeatedly unreachable or the dial keeps failing. Each retry increments the counter; once it crosses MaxHandoffRetries (default 3), performConnectionHandoff returns ErrMaxHandoffRetriesReached and processHandoffRequest closes the connection (handoff_worker.go:247-251).
Common situations: The new endpoint returned by MOVING is wrong/unreachable (firewall, DNS, wrong EndpointType for the network); the target node is down during a multi-shard migration storm; HandoffTimeout too short causing repeated dial aborts that each count as a retry.
Related errors
- MaxHandoffRetries must be between 1 and 10
- handoff queue is full, cannot queue new handoff requests - c
- connection is in invalid state for handoff
- circuit breaker is open, failing fast
- redis: connection not available
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/b991147460021fb7.json.
Report an issue: GitHub.