go-redis/redis · error

relaxed timeout must be greater than 0

Error message

relaxed timeout must be greater than 0

What it means

maintnotifications.ErrInvalidRelaxedTimeout (message: "relaxed timeout must be greater than 0") is returned by Config.Validate() when RelaxedTimeout <= 0 (config.go:158-160). RelaxedTimeout governs the extended read/write deadlines applied during MIGRATING/FAILING_OVER so in-flight ops survive increased latency; it must be a positive duration. (When defaults are applied via merge, a zero value is replaced by the 10s default, so this error only surfaces when Validate runs on a raw config with a non-positive value.)

Source

Thrown at maintnotifications/errors.go:11

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())

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Set RelaxedTimeout to a positive duration (e.g. 10*time.Second, the default).
  2. Use DefaultConfig()/merge-with-defaults so a zero value is filled in rather than rejected.
  3. Validate computed config values before assigning (guard against <= 0 from arithmetic).

Example fix

// before
cfg := &maintnotifications.Config{RelaxedTimeout: 0}
cfg.Validate() // errors
// after
cfg := maintnotifications.DefaultConfig()
cfg.RelaxedTimeout = 10 * time.Second
Defensive patterns

Strategy: validation

Validate before calling

cfg := maintnotifications.DefaultConfig()
if envRelaxed > 0 {
    cfg.RelaxedTimeout = time.Duration(envRelaxed) * time.Second
} // never assign a non-positive value
cfg.Validate()

Type guard

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

Try / catch

if err := cfg.Validate(); err != nil {
    if errors.Is(err, maintnotifications.ErrInvalidRelaxedTimeout) {
        cfg.RelaxedTimeout = 10 * time.Second // fall back to default
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Constructing maintnotifications.Config with RelaxedTimeout set to 0 or negative and calling cfg.Validate() (directly or via the client setup that validates) before/without default-merging.

Common situations: Explicitly zeroing the config struct, copy-pasting a partial config, or a negative value from an env-driven calculation that underflowed.

Related errors


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