{"id":"df103c839d54486f","repo":"go-redis/redis","slug":"connection-is-in-invalid-state-for-handoff","errorCode":null,"errorMessage":"connection is in invalid state for handoff","messagePattern":"connection is in invalid state for handoff","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"maintnotifications/errors.go","lineNumber":53,"sourceCode":"\tErrHandoffQueueFull = errors.New(logs.HandoffQueueFullError())\n)\n\n// Notification errors\nvar (\n\t// ErrInvalidNotification is returned when a notification is in an invalid format\n\tErrInvalidNotification = errors.New(logs.InvalidNotificationError())\n)\n\n// connection handoff errors\nvar (\n\t// ErrConnectionMarkedForHandoff is returned when a connection is marked for handoff\n\t// and should not be used until the handoff is complete\n\tErrConnectionMarkedForHandoff = errors.New(logs.ConnectionMarkedForHandoffErrorMessage)\n\t// ErrConnectionMarkedForHandoffWithState is returned when a connection is marked for handoff\n\t// and should not be used until the handoff is complete\n\tErrConnectionMarkedForHandoffWithState = errors.New(logs.ConnectionMarkedForHandoffErrorMessage + \" with state\")\n\t// ErrConnectionInvalidHandoffState is returned when a connection is in an invalid state for handoff\n\tErrConnectionInvalidHandoffState = errors.New(logs.ConnectionInvalidHandoffStateErrorMessage)\n)\n\n// shutdown errors\nvar (\n\t// ErrShutdown is returned when the maintnotifications manager is shutdown\n\tErrShutdown = errors.New(logs.ShutdownError())\n)\n\n// circuit breaker errors\nvar (\n\t// ErrCircuitBreakerOpen is returned when the circuit breaker is open\n\tErrCircuitBreakerOpen = errors.New(logs.CircuitBreakerOpenErrorMessage)\n)\n\n// circuit breaker configuration errors\nvar (\n\t// ErrInvalidCircuitBreakerFailureThreshold is returned when the circuit breaker failure threshold is invalid\n\tErrInvalidCircuitBreakerFailureThreshold = errors.New(logs.InvalidCircuitBreakerFailureThresholdError())","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/maintnotifications/errors.go#L35-L71","documentation":"Returned by performConnectionHandoff (handoff_worker.go:364) when conn.GetHandoffEndpoint() returns an empty string. A handoff was initiated for a connection, but no target endpoint was recorded, so there is nowhere to relocate it; shouldRetry=false so the connection is dropped rather than retried.","triggerScenarios":"A MOVING notification with a nil/empty newEndpoint led to a handoff being queued, but the connection's handoff endpoint field was never populated (or was cleared) by the time the worker ran performConnectionHandoff. This is an unexpected internal state — MOVING normally guarantees an endpoint or schedules a same-endpoint reconnect.","commonSituations":"A race where the connection's handoff state was reset between queuing and processing; a malformed MOVING that passed initial validation but carried no usable endpoint; concurrency between shutdown and handoff clearing the endpoint.","solutions":["Capture the full MOVING payload from logs (logs.InvalidNewEndpointInMovingNotification / InvalidNotification) to confirm the server sent an endpoint.","Check for any custom code that calls conn handoff-state setters and remove it; state should only be driven by the notification handler.","Upgrade go-redis — an empty endpoint at handoff time usually indicates a state-machine race fixed in recent versions.","If reproducing, file an issue with the conn ID and surrounding handoff log lines."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if errors.Is(err, maintnotifications.ErrConnectionInvalidHandoffState) {\n    // connection dropped; the next command uses a fresh connection. \n    // If recurring, capture MOVING payloads and report a possible state race.\n    return retryCommand(ctx, cmd)\n}","preventionTips":["Do not manipulate pool.Conn handoff state from application code.","Keep go-redis current — state-machine races are fixed in releases.","Reproduce with full handoff logs (conn ID) before reporting."],"tags":["maintnotifications","handoff","state","runtime"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}