docker/cli ยท error

invalid restart policy: maximum retry count cannot be negati

Error message

invalid restart policy: maximum retry count cannot be negative

What it means

Raised by convertRestartPolicy when a compose service uses the legacy top-level `restart:` string (not deploy.restart_policy) and parsing it yields a negative maximum retry count. Swarm stores MaxAttempts as an unsigned value, so a negative count is meaningless and rejected during stack conversion.

Source

Thrown at cli/compose/convert/service.go:498

		// TODO: log or error if both "service.restart" and "service.deploy.restartpolicy" are set.
		return &swarm.RestartPolicy{
			Condition:   swarm.RestartPolicyCondition(restartPolicy.Condition),
			Delay:       composetypes.ConvertDurationPtr(restartPolicy.Delay),
			MaxAttempts: restartPolicy.MaxAttempts,
			Window:      composetypes.ConvertDurationPtr(restartPolicy.Window),
		}, nil
	}
	if restart == "" {
		return nil, nil
	}

	// Fall back to the legacy service.restart restart-policy.
	policy, err := opts.ParseRestartPolicy(restart)
	if err != nil {
		return nil, err
	}
	if policy.MaximumRetryCount < 0 {
		return nil, errors.New("invalid restart policy: maximum retry count cannot be negative")
	}
	uint64Ptr := func(i int) *uint64 {
		if i <= 0 {
			return nil
		}
		p := uint64(i)
		return &p
	}

	switch policy.Name {
	case container.RestartPolicyDisabled, "":
		return nil, nil
	case container.RestartPolicyAlways, container.RestartPolicyUnlessStopped:
		return &swarm.RestartPolicy{
			Condition:   swarm.RestartPolicyConditionAny,
			MaxAttempts: uint64Ptr(policy.MaximumRetryCount),
		}, nil
	case container.RestartPolicyOnFailure:

View on GitHub (pinned to e9452d6e78)

Solutions

  1. Use `restart: on-failure` without a count for unlimited retries, or a non-negative count like `on-failure:5`
  2. Prefer the swarm-native form: `deploy.restart_policy: {condition: on-failure, max_attempts: 5}`
  3. Validate templated values so retry counts are >= 0 before deploy

Example fix

# before
restart: on-failure:-1
# after
deploy:
  restart_policy:
    condition: on-failure
    max_attempts: 5

When it happens

Trigger: `docker stack deploy` with a service like `restart: on-failure:-1` (or any on-failure:<negative> form) and no `deploy.restart_policy` overriding it. The legacy string is parsed via opts.ParseRestartPolicy and the MaximumRetryCount < 0 check fails.

Common situations: Users writing `on-failure:-1` intending 'retry forever' (the correct way is plain `on-failure` or `restart: always`); generated compose files with templated retry counts that go negative; porting configs from systems where -1 means unlimited.

Related errors


AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01). Data as JSON: /data/errors/b6c478bf9f0c6d1c.json. Report an issue: GitHub.