docker/cli · error
scale can only be used with replicated or replicated-job…
Error message
scale can only be used with replicated or replicated-job mode
What it means
Thrown by runServiceScale (cli/command/service/scale.go:108) when the inspected service's Spec.Mode is neither Replicated nor ReplicatedJob. Scaling works by writing to Replicated.Replicas or ReplicatedJob.TotalCompletions; global and global-job modes have no count field to mutate, so the switch statement falls through to its default branch.
Solutions
- Recreate the service in a scalable mode if a fixed count is required: `docker service create --mode replicated --replicas N ...`.
- For global services, scale horizontally by adding/removing swarm nodes rather than using `docker service scale`.
- Inspect the mode before scaling: `docker service inspect --format '{{json .Spec.Mode}}' <svc>` and skip scale for non-replicated modes.
Example fix
// before
docker service scale myservice=5 # myservice is --mode global
// after
docker service inspect --format '{{json .Spec.Mode}}' myservice
# => {"Global":{}} -> do not scale; scale by adding nodes instead Defensive patterns
Strategy: validation
Validate before calling
// Before scaling, confirm the service is in a scalable mode.
res, err := apiClient.ServiceInspect(ctx, id, client.ServiceInspectOptions{})
if err != nil { return err }
m := res.Service.Spec.Mode
if m.Replicated == nil && m.ReplicatedJob == nil {
return fmt.Errorf("service %s is not replicated/replicated-job; cannot scale", id)
}
// safe to scale now Type guard
// Narrows a swarm.ServiceMode to a scalable count field.
func scalableCount(m *swarm.ServiceMode) (set func(uint64), ok bool) {
if m.Replicated != nil {
return func(n uint64) { m.Replicated.Replicas = &n }, true
}
if m.ReplicatedJob != nil {
return func(n uint64) { m.ReplicatedJob.TotalCompletions = &n }, true
}
return nil, false
} Prevention
- Always inspect Spec.Mode before scripting a scale call.
- Reserve global mode for services that must run one-per-node.
- Tag services with a label recording their intended scaling strategy.
When it happens
Trigger: Running `docker service scale <svc>=N` against a service created with `--mode global` or `--mode global-job`. The ServiceInspect call succeeds, but neither case in the switch matches, hitting the default that returns this error.
Common situations: Operator forgets a service was deployed globally and scripts a scale call; a Compose file sets `deploy.mode: global` but the pipeline assumes it can scale; migrating a service between modes without recreating it.
Related errors
- replicas can only be used with replicated mode
- placement preference must be of the format
- replicas can only be used with replicated or replicated-job…
- replicas-max-per-node can only be used with replicated or…
- max-concurrent can only be used with replicated-job mode
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/b51de2da9f218a47.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/service/scale.go:108
}
}
return errors.Join(errs...)
}
func runServiceScale(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string, scale uint64) (warnings []string, _ error) {
res, err := apiClient.ServiceInspect(ctx, serviceID, client.ServiceInspectOptions{})
if err != nil {
return nil, err
}
serviceMode := &res.Service.Spec.Mode
switch {
case serviceMode.Replicated != nil:
serviceMode.Replicated.Replicas = &scale
case serviceMode.ReplicatedJob != nil:
serviceMode.ReplicatedJob.TotalCompletions = &scale
default:
return nil, errors.New("scale can only be used with replicated or replicated-job mode")
}
response, err := apiClient.ServiceUpdate(ctx, res.Service.ID, client.ServiceUpdateOptions{
Version: res.Service.Version,
Spec: res.Service.Spec,
})
if err != nil {
return nil, err
}
return response.Warnings, nil
}
// completeScaleArgs returns a completion function for the args of the scale command.
// It completes service names followed by "=", suppressing the trailing space.
func completeScaleArgs(dockerCli command.Cli) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// reuse the existing logic for configurable completion of service names and IDs.
completions, directive := completeServiceNames(dockerCli)(cmd, args, toComplete)View on GitHub (pinned to 4f84911bfe)