go-redis/redis · error

circuit breaker reset timeout must be >= 0

Error message

circuit breaker reset timeout must be >= 0

What it means

Returned by Config.Validate() (maintnotifications/config.go:181-183) when Config.CircuitBreakerResetTimeout < 0. This is how long a circuit breaker stays open before probing the endpoint again (circuit_breaker.go:90). Zero is valid (probe immediately on next check); negatives are rejected.

Source

Thrown at maintnotifications/errors.go:73

// 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 (
	// ErrInvalidCircuitBreakerFailureThreshold is returned when the circuit breaker failure threshold is invalid
	ErrInvalidCircuitBreakerFailureThreshold = errors.New(logs.InvalidCircuitBreakerFailureThresholdError())
	// ErrInvalidCircuitBreakerResetTimeout is returned when the circuit breaker reset timeout is invalid
	ErrInvalidCircuitBreakerResetTimeout = errors.New(logs.InvalidCircuitBreakerResetTimeoutError())
	// ErrInvalidCircuitBreakerMaxRequests is returned when the circuit breaker max requests is invalid
	ErrInvalidCircuitBreakerMaxRequests = errors.New(logs.InvalidCircuitBreakerMaxRequestsError())
)

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Set CircuitBreakerResetTimeout to 0 (immediate probe) or a positive duration (default 60s).
  2. Clamp computed durations: `if d < 0 { d = 0 }`.
  3. Keep it reasonable (tens of seconds) to avoid hammering a dead endpoint.

Example fix

// before
cfg := &maintnotifications.Config{CircuitBreakerResetTimeout: -10 * time.Second}

// after
cfg := &maintnotifications.Config{CircuitBreakerResetTimeout: 60 * time.Second}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.CircuitBreakerResetTimeout < 0 {
    cfg.CircuitBreakerResetTimeout = 60 * time.Second
}
if err := cfg.Validate(); err != nil {
    return fmt.Errorf("maint config: %w", err)
}

Type guard

func validResetTimeout(d time.Duration) bool { return d >= 0 }

Prevention

When it happens

Trigger: Setting Options.MaintNotificationsConfig.CircuitBreakerResetTimeout to a negative time.Duration, then constructing the client which runs Validate().

Common situations: A computed duration that goes negative (e.g. base - jitter where jitter > base); parsing a negative number with a time unit; using -1s as a 'disable' sentinel.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/07944655b0842c24.json. Report an issue: GitHub.