microsoft/garnet · error · Exception

invalid failover status

Error message

invalid failover status

What it means

Thrown by FailoverUtils.GetFailoverStatus when the supplied FailoverStatus? cannot be mapped to an info-command string. The switch enumerates all eight defined FailoverStatus members, so the default arm only fires for a null status or a value cast outside the enum range. It surfaces during CLUSTER failover when reporting state via the INFO command.

Source

Thrown at libs/cluster/Server/Failover/FailoverStatus.cs:43

        /// <summary>
        /// Convert failover to string message for info command.
        /// </summary>
        /// <param name="status">Failover status type.</param>
        /// <returns>String message for provided status, otherwise exception is thrown.</returns>
        /// <exception cref="Exception"></exception>
        public static string GetFailoverStatus(FailoverStatus? status)
        {
            return status switch
            {
                FailoverStatus.NO_FAILOVER => "no-failover",
                FailoverStatus.BEGIN_FAILOVER => "begin-failover",
                FailoverStatus.ISSUING_PAUSE_WRITES => "issuing-pause-writes",
                FailoverStatus.WAITING_FOR_SYNC => "waiting-for-sync",
                FailoverStatus.FAILOVER_IN_PROGRESS => "failover-in-progress",
                FailoverStatus.TAKING_OVER_AS_PRIMARY => "taking-over-as-primary",
                FailoverStatus.FAILOVER_COMPLETED => "failover-completed",
                FailoverStatus.FAILOVER_ABORTED => "failover-aborted",
                _ => throw new Exception("invalid failover status"),
            };
        }
    }
}

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Ensure the failover state machine initializes the status field to NO_FAILOVER before any INFO/GetFailoverStatus read path can observe it.
  2. If the caller can legitimately observe null, handle it before calling (e.g. treat null as NO_FAILOVER) instead of relying on the switch default.
  3. When extending FailoverStatus, add the new arm to the switch to keep it exhaustive.

Example fix

// before
return FailoverUtils.GetFailoverStatus(currentStatus);
// after
var status = currentStatus ?? FailoverStatus.NO_FAILOVER;
return FailoverUtils.GetFailoverStatus(status);
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling GetFailoverStatus
var status = currentStatus ?? FailoverStatus.NO_FAILOVER;
if ((byte)status > (byte)FailoverStatus.FAILOVER_ABORTED)
    throw new ArgumentOutOfRangeException(nameof(status), status, "Unknown FailoverStatus");
var msg = FailoverUtils.GetFailoverStatus(status);

Prevention

When it happens

Trigger: Calling GetFailoverStatus(null), or casting an arbitrary byte to (FailoverStatus) outside 0..7 (e.g. an unsafe cast or uninitialized field read before the failover state machine sets a value).

Common situations: A failover status field read before initialization (still null), a concurrent reset that nulls the status mid-read, or a future enum member added without updating this switch.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/bda0de6c5b128452. Report an issue: GitHub.