docker/cli · error

replicas can only be used with replicated or replicated-job…

Error message

replicas can only be used with replicated or replicated-job mode

What it means

Returned by convertDeployMode (service.go:636-637) when deploy.mode is 'global-job' AND deploy.replicas is also set. Global-job mode runs exactly one task per node, so a replica count is meaningless and the converter rejects it. Only 'replicated' and 'replicated-job' modes honor replicas.

Solutions

  1. Remove 'replicas:' when using mode: global-job.
  2. If you need a fixed task count, switch mode to 'replicated-job' (or 'replicated') and keep replicas.
  3. Validate with 'docker compose config' before deploying.

Example fix

# before
deploy:
  mode: global-job
  replicas: 3

# after
deploy:
  mode: global-job
Defensive patterns

Strategy: validation

Validate before calling

// Validate deploy mode/replicas consistency for Swarm conversion.
func validateDeployMode(mode string, replicas *uint64) error {
    if (mode == "global" || mode == "global-job") && replicas != nil {
        return errors.New("replicas can only be used with replicated or replicated-job mode")
    }
    return nil
}

Type guard

// deployModeAllowsReplicas reports whether 'mode' honors a replicas count.
func deployModeAllowsReplicas(mode string) bool {
    switch mode {
    case "replicated", "replicated-job", "":
        return true
    default: // global, global-job
        return false
    }
}

Prevention

When it happens

Trigger: In docker-compose.yml for a Swarm-deployed service: deploy: { mode: global-job, replicas: 3 }. The switch case at line 635 sees mode 'global-job' with a non-nil replicas pointer and returns the error.

Common situations: Copy-pasting a deploy block from a replicated service into a global-job service. Misunderstanding global-job semantics (one task per node). Templating that always emits replicas.

Related errors


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

Appendix: source

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

	for name, value := range source {
		switch value {
		case nil:
			output = append(output, name)
		default:
			output = append(output, name+"="+*value)
		}
	}
	sort.Strings(output)
	return output
}

func convertDeployMode(mode string, replicas *uint64) (swarm.ServiceMode, error) {
	serviceMode := swarm.ServiceMode{}

	switch mode {
	case "global-job":
		if replicas != nil {
			return serviceMode, errors.New("replicas can only be used with replicated or replicated-job mode")
		}
		serviceMode.GlobalJob = &swarm.GlobalJob{}
	case "global":
		if replicas != nil {
			return serviceMode, errors.New("replicas can only be used with replicated or replicated-job mode")
		}
		serviceMode.Global = &swarm.GlobalService{}
	case "replicated-job":
		serviceMode.ReplicatedJob = &swarm.ReplicatedJob{
			MaxConcurrent:    replicas,
			TotalCompletions: replicas,
		}
	case "replicated", "":
		serviceMode.Replicated = &swarm.ReplicatedService{Replicas: replicas}
	default:
		return serviceMode, fmt.Errorf("unknown mode: %s", mode)
	}
	return serviceMode, nil

View on GitHub (pinned to 4f84911bfe)