go-redis/redis · error
failed to enable maintnotifications: %w
Error message
failed to enable maintnotifications: %w
What it means
Thrown when the CLIENT MAINT_NOTIFICATIONS handshake returns a redis-side error and MaintNotificationsConfig.Mode is ModeEnabled. The handshake is attempted after HELLO succeeds (RESP3); a server-side rejection means the server does not support the command, so the client fails the connection closed rather than continuing without notifications.
Source
Thrown at redis.go:978
if !isRedisError(maintNotifHandshakeErr) {
// if not redis error, fail the connection
cn.GetStateMachine().Transition(pool.StateClosed)
return maintNotifHandshakeErr
}
c.optLock.Lock()
// handshake failed - check and modify config atomically
switch c.opt.MaintNotificationsConfig.Mode {
case maintnotifications.ModeEnabled:
// enabled mode, fail the connection
c.optLock.Unlock()
cn.GetStateMachine().Transition(pool.StateClosed)
// Record handshake failure metric
if errorCallback := pool.GetMetricErrorCallback(); errorCallback != nil {
errorCallback(ctx, "HANDSHAKE_FAILED", cn, "HANDSHAKE_FAILED", true, 0)
}
return fmt.Errorf("failed to enable maintnotifications: %w", maintNotifHandshakeErr)
default: // will handle auto and any other
// Disabling logging here as it's too noisy.
// TODO: Enable when we have a better logging solution for log levels
// internal.Logger.Printf(ctx, "auto mode fallback: maintnotifications disabled due to handshake error: %v", maintNotifHandshakeErr)
c.opt.MaintNotificationsConfig.Mode = maintnotifications.ModeDisabled
c.optLock.Unlock()
// auto mode, disable maintnotifications and continue
if initErr := c.disableMaintNotificationsUpgrades(); initErr != nil {
// Log error but continue - auto mode should be resilient
internal.Logger.Printf(ctx, "failed to disable maintnotifications in auto mode: %v", initErr)
}
}
}
}
if !c.opt.DisableIdentity && !c.opt.DisableIndentity {
libName := ""
libVer := Version()View on GitHub (pinned to 36d97525cd)
Solutions
- Use ModeAuto (default) so the client downgrades to disabled on rejection instead of failing the connection.
- Upgrade the server to Redis 8.8+ which supports CLIENT MAINT_NOTIFICATIONS, and enable any required feature flags.
- If the feature is mandatory for your app, route ModeEnabled clients only to endpoints known to support it.
- Inspect the wrapped error text for the exact server rejection (unknown command, disabled, permission).
Example fix
// before
cfg := &redis.MaintNotificationsConfig{Mode: redis.ModeEnabled}
opt := &redis.Options{Addr: addr, Protocol: 3, MaintNotificationsConfig: cfg}
// Redis 7.x rejects CLIENT MAINT_NOTIFICATIONS
// after
cfg := &redis.MaintNotificationsConfig{Mode: redis.ModeAuto}
opt := &redis.Options{Addr: addr, Protocol: 3, MaintNotificationsConfig: cfg} Defensive patterns
Strategy: validation
Validate before calling
// Check CLIENT MAINT_NOTIFICATIONS support before requiring it.
// Use redis-cli or INFO to confirm Redis >= 8.8.
if !serverSupportsCommand(ctx, probeClient, "client|maint_notifications") {
return errors.New("server lacks CLIENT MAINT_NOTIFICATIONS")
} Try / catch
if err := client.Ping(ctx).Err(); err != nil {
if strings.Contains(err.Error(), "failed to enable maintnotifications") {
// server rejected CLIENT MAINT_NOTIFICATIONS; switch to ModeAuto
}
} Prevention
- Use ModeAuto in mixed-version fleets so one RESP3-but-old server does not break all connections.
- Track the server command list (COMMAND DOCS) during provisioning to verify feature availability.
- Reserve ModeEnabled for environments where you control the Redis version.
When it happens
Trigger: Options.Protocol = 3, HELLO succeeded, Mode == ModeEnabled, and the server returned a redis error to CLIENT MAINT_NOTIFICATIONS (e.g. ERR unknown command on Redis < 8.8, or search/cluster mode that rejects it). Non-redis errors (transport) fail the connection unconditionally before reaching this branch.
Common situations: Server is Redis 6/7 with RESP3 but predates CLIENT MAINT_NOTIFICATIONS (added in 8.8); managed Redis that blocks the command; mode explicitly set to ModeEnabled against an endpoint that does not advertise the feature; mixing a ModeEnabled client with a Redis version that gate-gates the command behind a flag.
Related errors
- failed to enable maintnotifications: server does not support
- MaxWorkers must be greater than or equal to 0
- handoff queue size must be greater than 0
- post-handoff relaxed duration must be greater than or equal
- invalid endpoint type
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/9fbbd10393f06b90.json.
Report an issue: GitHub.