argoproj/argo-workflows · error

duration has to be positive, current duration: %v

Error message

duration has to be positive, current duration: %v 

What it means

ContainerSetTemplate.GetRetryStrategy parses the RetryStrategy.Duration string into a time.Duration and rejects negative values, because backoff durations used for retrying failed containers must be >= 0. A negative duration cannot produce a valid wait.Backoff.

Source

Thrown at pkg/apis/workflow/v1alpha1/container_set_template_types.go:47

func (in *ContainerSetTemplate) GetRetryStrategy() (wait.Backoff, error) {
	if in == nil || in.RetryStrategy == nil || in.RetryStrategy.Retries == nil {
		return wait.Backoff{Steps: 1}, nil
	}

	backoff := wait.Backoff{Steps: in.RetryStrategy.Retries.IntValue()}

	if in.RetryStrategy.Duration == "" {
		return backoff, nil
	}

	baseDuration, err := time.ParseDuration(in.RetryStrategy.Duration)
	if err != nil {
		return wait.Backoff{}, err
	}

	if baseDuration < time.Duration(0) {
		return wait.Backoff{}, fmt.Errorf("duration has to be positive, current duration: %v ", baseDuration)
	}

	backoff.Duration = baseDuration
	return backoff, nil
}

func (in *ContainerSetTemplate) GetContainers() []corev1.Container {
	var ctrs []corev1.Container
	for _, t := range in.GetGraph() {
		c := t.Container
		c.VolumeMounts = append(c.VolumeMounts, in.VolumeMounts...)
		ctrs = append(ctrs, c)
	}
	return ctrs
}

func (in *ContainerSetTemplate) HasContainerNamed(n string) bool {
	for _, c := range in.GetContainers() {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set retryStrategy.duration to a non-negative Go duration string, e.g. "30s".
  2. Remove the leading '-' from the duration value in the manifest.
  3. Validate the duration with time.ParseDuration before submitting the workflow.

Example fix

// before
retryStrategy:
  duration: -5s
// after
retryStrategy:
  duration: 5s
Defensive patterns

Strategy: validation

Validate before calling

if d, err := time.ParseDuration(rs.Duration); err != nil || d < 0 {
    return fmt.Errorf("invalid retry duration %q", rs.Duration)
}

Try / catch

backoff, err := cs.GetRetryStrategy()
if err != nil {
    if strings.Contains(err.Error(), "duration has to be positive") {
        return fmt.Errorf("fix retryStrategy.duration: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Setting retryStrategy.duration in a ContainerSetTemplate to a string that time.ParseDuration resolves to a negative value, e.g. "-5s", then calling GetRetryStrategy (directly or via validation of the ContainerSet).

Common situations: Copy-pasted retry config with a stray minus sign; templating/variable substitution producing "-{{delay}}"; confusing required-positivity with zero-allowed (0 is accepted here, negative is not).

Related errors


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