docker/cli · error

duration cannot be negative

Error message

duration cannot be negative

What it means

Returned by PositiveDurationOpt.Set (opts/duration.go:22) after successfully parsing a Go duration string whose value is negative. PositiveDurationOpt wraps DurationOpt but adds the constraint that only non-negative durations are accepted. The underlying parse (time.ParseDuration) succeeds, then the sign check fails.

Solutions

  1. Remove the negative sign from the duration value.
  2. If a zero duration is acceptable, use '0s' or '0' instead of a negative value.
  3. Validate computed duration values before formatting them into a CLI flag string.

Example fix

// before: negative duration
// docker run --stop-timeout=-5 nginx

// after: positive or zero
// docker run --stop-timeout=5 nginx
Defensive patterns

Strategy: validation

Validate before calling

func validatePositiveDuration(s string) error {
    d, err := time.ParseDuration(s)
    if err != nil {
        return err
    }
    if d < 0 {
        return fmt.Errorf("duration %s must not be negative", s)
    }
    return nil
}

Try / catch

if err := durationOpt.Set(value); err != nil {
    if err.Error() == "duration cannot be negative" {
        return fmt.Errorf("timeout value %q must be >= 0", value)
    }
    return err
}

Prevention

When it happens

Trigger: A CLI flag backed by PositiveDurationOpt receives a negative duration string, e.g., '--stop-timeout=-5' or '--timeout=-1s'. The string parses as a valid Go duration but the numeric value is less than zero.

Common situations: Typo with a minus sign in a timeout/stop-timeout flag, a computed duration value that unexpectedly becomes negative and is formatted into the flag, or confusion about whether a flag accepts negative values.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/ad5b332c05215942. Report an issue: GitHub.

Appendix: source

Thrown at opts/duration.go:22

	"errors"
	"time"
)

// PositiveDurationOpt is an option type for time.Duration that uses a pointer.
// It behave similarly to DurationOpt but only allows positive duration values.
type PositiveDurationOpt struct {
	DurationOpt
}

// Set a new value on the option. Setting a negative duration value will cause
// an error to be returned.
func (d *PositiveDurationOpt) Set(s string) error {
	err := d.DurationOpt.Set(s)
	if err != nil {
		return err
	}
	if *d.DurationOpt.value < 0 {
		return errors.New("duration cannot be negative")
	}
	return nil
}

// DurationOpt is an option type for time.Duration that uses a pointer. This
// allows us to get nil values outside, instead of defaulting to 0
type DurationOpt struct {
	value *time.Duration
}

// NewDurationOpt creates a DurationOpt with the specified duration
func NewDurationOpt(value *time.Duration) *DurationOpt {
	return &DurationOpt{
		value: value,
	}
}

// Set a new value on the option

View on GitHub (pinned to 4f84911bfe)