Remove a Docker Swarm Service Without Guessing
docker service rm deletes a Swarm service the moment you press enter, with no confirmation prompt and no built-in undo. The installed Docker CLI here is 29.8.1 from docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow ten minutes for a single service if you already know its name. You need access to a Swarm manager and permission to use the Docker daemon. This command is destructive and can disrupt every task belonging to the selected service.
Checkpoint
Do not run the removal command until you have recorded the exact service name and checked that it is safe to stop.
1. Check the local command
Read the installed command's help before using it. This is an ordinary, read-only check and normally needs no elevated privileges:
$ docker service rm --help
Usage: docker service rm SERVICE [SERVICE...]
Remove one or more services
Aliases:
docker service rm, docker service remove
The local manpage documents the same syntax, SERVICE [SERVICE...]. The command takes one or more service names or IDs and has no removal options: notably, there is no local --force switch to make this safer or more forceful.
Check which executable and package version will handle the request:
$ command -v docker
/usr/bin/docker
$ docker --version
Docker version 29.8.1, build 4a63305
$ dpkg-query -W -f='${Package} ${Version}\n' docker-ce-cli
docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble
2. Confirm this shell reaches a manager
docker service rm manages Swarm services, so run it against a manager, not an ordinary worker. Ask the daemon for its Swarm state without changing anything:
$ docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
active true
You need an active true result for this shell to count as a manager. An inactive false result, as you would see on a non-Swarm host, means stop here: sudo will not turn a worker into a manager. Connect to the correct manager or ask the Swarm operator to make the change instead.
Some installations need elevated privileges to reach the Docker socket. Use sudo only for the Docker command itself if your account is not in the Docker group:
$ sudo docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
active true
Membership of the Docker group is effectively administrative access on the host. Treat both the socket and the command as privileged operations.
3. Identify the target service
List services and stop if the output is not what you expect:
$ docker service ls
ID NAME MODE REPLICAS IMAGE
abc123def456 payments-api replicated 3/3 registry.example/payments:2026.09
Names are easier to review than short IDs, so use an exact name from this output, such as payments-api. If several services look like candidates, inspect each one before choosing:
$ docker service inspect --pretty payments-api
ID: abc123def456...
Name: payments-api
Service Mode: Replicated
Replicas: 3
UpdateStatus:
State: completed
The formatting and fields vary with the service and CLI version. Confirm the image, replica count, labels and deployment owner from the full inspection output or your deployment files: do not infer the target from a similar-looking name.
Destructive checkpoint: record the service name, ID, image and the file or release that can recreate it. Removing a service is not an update and provides no built-in undo. If the service came from a stack or deployment process, keep that definition to hand before proceeding.
4. Remove one service
When the target is confirmed, run the command on the manager:
$ docker service rm payments-api
payments-api
The printed name is Docker's acknowledgement that the removal request was accepted, and the service is now gone from the Swarm. Because there is no confirmation prompt, a typo can remove a different service immediately, so check the command line once more before pressing enter.
For several independently confirmed services, pass each name as a separate argument:
$ docker service rm old-api old-worker
old-api
old-worker
Do not build this argument list from unreviewed text or a broad shell expansion. A service name containing unexpected input deserves investigation, not a place in a privileged command.
5. Verify the service is gone
List the services again and search for the exact name:
$ docker service ls
$ docker service ls --filter name=payments-api
ID NAME MODE REPLICAS IMAGE
An empty filtered result means the manager no longer lists that service. The table can also be empty because nothing matches, so check the command's exit status when scripting:
$ docker service ls --format '{{.Name}}' | grep -Fx -- payments-api
$ printf 'grep status: %s\n' "$?"
grep status: 1
Status 1 from grep means no exact line matched. Status 0 would mean the service name still appears, so investigate the manager connection and any spelling difference before assuming removal failed.
Recovery
Removal is not a rollback. If you need the service again, recreate it from the verified stack file, deployment definition or a recorded docker service create command. Recreating it may assign a new service ID and can require registry credentials, networks, secrets and configs to already exist. Do not invent those values from memory.
Common traps
- "This node is not a swarm manager." Run the command on a manager with
ControlAvailableset totrue. - "service not found" or a similar lookup error. Run
docker service lson the same manager and copy the exact name or ID: a local container name is not necessarily a Swarm service name. - Access denied to the Docker socket. Use the approved administrative path for this host. Do not loosen socket permissions as a quick fix.
- The service is still visible. Check you are querying the same manager endpoint and that the name is exact: a separate context or remote host can show a different Swarm.
- You expected a confirmation prompt. This command has none. Build a review step around
docker service lsanddocker service inspectinstead.
Done means
- Confirmed the CLI. Version and command syntax were checked locally.
- Ran it as a manager. The command ran against a Swarm manager with administrative access.
- Inspected before deleting. The exact service name or ID was confirmed before removal.
- Removed deliberately. No unreviewed expansion fed the argument list.
- Verified the result. A second listing no longer shows the target.
- Kept a way back. The deployment definition needed for a deliberate recreation is still available.