argoproj/argo-workflows · error

maxDelay cannot be less than 0

Error message

maxDelay cannot be less than 0

What it means

validateProxyParams rejects a negative maxDelay, the ceiling on exponential backoff between reconnection attempts. A negative ceiling breaks the backoff algorithm, so NewSessionProxy fails fast with this message. Pure input validation.

Source

Thrown at util/sqldb/session.go:68

	KubectlConfig kubernetes.Interface
	Namespace     string
	DBConfig      config.DBConfig
	Username      string
	Password      string
	MaxRetries    int
	BaseDelay     time.Duration
	MaxDelay      time.Duration
}

func validateProxyParams(proxy *SessionProxy) error {
	if proxy.maxRetries < 0 {
		return fmt.Errorf("maxRetries cannot be less than 0")
	}
	if proxy.baseDelay < 0 {
		return fmt.Errorf("baseDelay cannot be less than 0")
	}
	if proxy.maxDelay < 0 {
		return fmt.Errorf("maxDelay cannot be less than 0")
	}
	if proxy.retryMultiple < 0 {
		return fmt.Errorf("retryMultiple cannot be less than 0")
	}
	return nil
}

// NewSessionProxy creates a new SessionProxy with the given configuration
func NewSessionProxy(ctx context.Context, config SessionProxyConfig) (*SessionProxy, error) {
	dbType := dbTypeFromConfig(&config.DBConfig)
	proxy := &SessionProxy{
		kubectlConfig: config.KubectlConfig,
		namespace:     config.Namespace,
		dbConfig:      &config.DBConfig,
		username:      config.Username,
		password:      config.Password,
		dbType:        dbType,
		maxRetries:    config.MaxRetries,

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set MaxDelay (or DBReconnectConfig.MaxDelaySeconds) to 0 or positive — 0 falls back to the default 30s.
  2. Fix the negative value in the dbReconnectConfig.maxDelaySeconds config entry.
  3. Ensure maxDelay is not unintentionally below baseDelay when computing both from one expression.
  4. If MaxDelay is derived at runtime, clamp: if d < 0 { d = 0 }.

Example fix

// before
SessionProxyConfig{MaxDelay: -30 * time.Second}
// after
SessionProxyConfig{MaxDelay: 30 * time.Second}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.MaxDelay < 0 {
    return fmt.Errorf("MaxDelay must be >= 0, got %s", cfg.MaxDelay)
}
if cfg.BaseDelay >= 0 && cfg.MaxDelay >= 0 && cfg.MaxDelay < cfg.BaseDelay {
    return fmt.Errorf("MaxDelay should not be smaller than BaseDelay")
}

Try / catch

if err := NewSessionProxy(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "maxDelay cannot be less than 0") {
        cfg.MaxDelay = 0 // triggers 30s default
        return NewSessionProxy(ctx, cfg)
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewSessionProxy with SessionProxyConfig.MaxDelay < 0, or DBConfig.DBReconnectConfig.MaxDelaySeconds < 0 (converted to a negative time.Duration before validation).

Common situations: Negative maxDelaySeconds in the workflow-controller persistence config; YAML parsing quirks or human typo when hand-editing the controller ConfigMap; generated config where a subtraction went negative.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/23ca5a9451e9ce28. Report an issue: GitHub.