go-redis/redis · error

post-handoff relaxed duration must be greater than or equal

Error message

post-handoff relaxed duration must be greater than or equal to 0

What it means

Returned by Config.Validate() (maintnotifications/config.go:173-175) when Config.PostHandoffRelaxedDuration is negative. This duration keeps relaxed read/write timeouts on a freshly handed-off connection to absorb latency during cluster transitions (handoff_worker.go). Zero is valid and means 'use the default of 2 * RelaxedTimeout'.

Source

Thrown at maintnotifications/errors.go:14

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

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Set PostHandoffRelaxedDuration to 0 to use the default (2 * RelaxedTimeout, config.go:286).
  2. Set it to an explicit non-negative duration you measured acceptable for post-handoff jitter.
  3. Guard any computed duration with a `if d < 0 { d = 0 }` clamp before assignment.

Example fix

// before
cfg := &maintnotifications.Config{PostHandoffRelaxedDuration: -2 * time.Second}

// after
cfg := &maintnotifications.Config{PostHandoffRelaxedDuration: 0} // default
Defensive patterns

Strategy: validation

Validate before calling

if cfg.PostHandoffRelaxedDuration < 0 {
    cfg.PostHandoffRelaxedDuration = 0 // -> 2 * RelaxedTimeout
}
if err := cfg.Validate(); err != nil {
    return fmt.Errorf("maint config: %w", err)
}

Type guard

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

Prevention

When it happens

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

Common situations: Subtracting durations in config that can yield a negative result (e.g. handoffTimeout - margin when margin is larger); passing a parsed negative number with a time unit; treating -1s as a 'disabled' flag.

Related errors


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