docker/cli · error

unknown mode

Error message

unknown mode: %s

What it means

Returned by convertDeployMode's default branch when deploy.mode is not one of 'global-job', 'global', 'replicated-job', or 'replicated' (service.go:631-655). For Swarm conversion the deploy mode must be a recognized service mode.

Solutions

  1. Set deploy.mode to 'replicated', 'global', 'replicated-job', or 'global-job'.
  2. Omit deploy.mode to default to replicated.
  3. Remember 'replicas' is only valid with 'replicated'/'replicated-job' (other modes reject it).

Example fix

// before
deploy:
  mode: replica
  replicas: 3
// after
deploy:
  mode: replicated
  replicas: 3
Defensive patterns

Strategy: validation

Validate before calling

var validDeployModes = map[string]bool{
    "": true, "replicated": true, "global": true, "replicated-job": true, "global-job": true,
}
func validateDeployModes(cfg *composetypes.Config) error {
    for _, svc := range cfg.Services {
        if m := svc.Deploy.Mode; !validDeployModes[m] {
            return fmt.Errorf("unknown mode: %s", m)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Setting deploy.mode to an unsupported string. Reached at service.go:652 default case after the four valid cases plus empty string (treated as replicated) fail to match.

Common situations: Typo such as 'replica' or 'globalized'; using a mode valid only for `docker compose` (non-Swarm) deployments; leftover experimental mode names.

Related errors


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

Appendix: source

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

	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
}

func convertDNSConfig(dns []string, dnsSearch []string) *swarm.DNSConfig {
	if len(dns) > 0 || len(dnsSearch) > 0 {
		return &swarm.DNSConfig{
			Nameservers: toNetipAddrSlice(dns),
			Search:      dnsSearch,
		}
	}
	return nil
}

func toNetipAddrSlice(ips []string) []netip.Addr {
	if len(ips) == 0 {
		return nil
	}

View on GitHub (pinned to 4f84911bfe)