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
- Set retryStrategy.duration to a non-negative Go duration string, e.g. "30s".
- Remove the leading '-' from the duration value in the manifest.
- 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
- Never emit duration strings from templates with a possible leading '-'.
- Unit-test retry configs with time.ParseDuration before submit.
- Remember 0 is allowed, negative is not — clamp negative values to 0 or a positive default.
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
- containers must have at least one container
- containers%s
- volumeMounts[%d].mountPath '%s' already mounted in %s
- failed to get retry strategy: %w
- successCondition, failureCondition and outputs are not suppo
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/8195a128867f34c1.
Report an issue: GitHub.