docker/cli · error

no replica count

Error message

no replica count

What it means

In `replicatedProgressUpdater.update()` (progress.go:294-296), the method re-checks that `service.Spec.Mode.Replicated` and `service.Spec.Mode.Replicated.Replicas` are non-nil. The updater was initialized in `initializeUpdater()` (line 235) only when both were non-nil, but `ServiceProgress` re-inspects the service on every loop iteration (line 93). If between iterations the service was updated to remove its replica count (e.g., mode changed to global), this re-check fails and returns the error. This is a race condition between progress monitoring and a concurrent service update.

Solutions

  1. Avoid modifying a service's mode while creation progress monitoring is running
  2. Use `--detach` when creating the service if concurrent modifications are expected
  3. Re-run `docker service ps <service>` to check status after the conflicting update completes

Example fix

# problematic: two concurrent operations
docker service create --name web --mode replicated --replicas 3 --image nginx &
# simultaneously in another terminal:
docker service update --mode global web  # triggers the race

# fix: use --detach to avoid blocking progress monitoring
docker service create --detach --name web --mode replicated --replicas 3 --image nginx
Defensive patterns

Strategy: try-catch

Validate before calling

// Before calling ServiceProgress, ensure the service has a stable mode
func hasStableReplicaCount(ctx context.Context, c client.APIClient, svcID string) bool {
    res, err := c.ServiceInspect(ctx, svcID, client.ServiceInspectOptions{})
    if err != nil {
        return false
    }
    return res.Service.Spec.Mode.Replicated != nil &&
        res.Service.Spec.Mode.Replicated.Replicas != nil
}

Try / catch

// Handle the race condition gracefully
err := progress.ServiceProgress(ctx, apiClient, svcID, progressWriter)
if err != nil && strings.Contains(err.Error(), "no replica count") {
    // Service mode likely changed concurrently; retry once or use --detach
    log.Printf("service %s mode changed during progress monitoring", svcID)
}

Prevention

When it happens

Trigger: While `docker service create` (without `--detach`) is monitoring convergence progress, another process or user simultaneously updates the service to change its mode (e.g., `docker service update --mode global myservice`), causing the replicated mode or replica count to become nil on the next inspect.

Common situations: Concurrent service modifications during creation/convergence monitoring. Most likely in automation pipelines where one process creates the service and another immediately modifies it.

Related errors


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

Appendix: source

Thrown at cli/command/service/progress/progress.go:296

		errMsg = errMsg[:maxWidth-1] + "…"
	}
	return errMsg
}

type replicatedProgressUpdater struct {
	progressOut progress.Output

	// used for mapping slots to a contiguous space
	// this also causes progress bars to appear in order
	slotMap map[int]int

	initialized bool
	done        bool
}

func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) {
	if service.Spec.Mode.Replicated == nil || service.Spec.Mode.Replicated.Replicas == nil {
		return false, errors.New("no replica count")
	}
	replicas := *service.Spec.Mode.Replicated.Replicas

	if !u.initialized {
		u.slotMap = make(map[int]int)

		// Draw progress bars in order
		writeOverallProgress(u.progressOut, 0, int(replicas), rollback)

		if replicas <= maxProgressBars {
			for i := uint64(1); i <= replicas; i++ {
				progress.Update(u.progressOut, fmt.Sprintf("%d/%d", i, replicas), " ")
			}
		}
		u.initialized = true
	}

	tasksBySlot := u.tasksBySlot(tasks, activeNodes)

View on GitHub (pinned to 4f84911bfe)