Inspect Docker Swarm Tasks with docker stack ps
A stack looks fine in the service list, yet something keeps restarting, and docker stack ps is the command that shows you which task and why. This guide covers filtering by node or state, and switching between readable and script-friendly output, in about ten minutes. The examples use Docker CE CLI 29.8.1, package 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.
What you need:
- The Docker CLI and access to a Docker daemon.
- A stack name. Not a service name, not a Compose file path.
- A Swarm manager. This is a cluster-management command. A worker node, a stopped daemon or a non-Swarm Docker context cannot provide the task list.
- Normally no
sudo. Nothing here changes a service, task, stack or Swarm, so there is nothing to undo.
1. Check the installed command
Start with read-only checks. This confirms the binary, version and option spelling before you build a diagnostic command:
$ command -v docker
/usr/bin/docker
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker stack ps --help
Usage: docker stack ps [OPTIONS] STACK
The final argument is mandatory. It is the stack name, not a service name and not a Compose file path.
Checkpoint
If the help text is different, use the syntax printed by your installed CLI.
2. List every task in the stack
Replace STACK_NAME with the exact name shown by docker stack ls. Listing stacks is also read-only:
$ docker stack ls
NAME SERVICES
STACK_NAME 3
$ docker stack ps STACK_NAME
The default table includes the task ID, task name, image, node, desired state, current state, error and ports. Docker may show abbreviated IDs and image details in the default view.
The list can include tasks that have stopped or failed, so a row's presence does not mean a healthy service.
Warning
If Docker says the node is not a Swarm manager, stop there. Run the command through a Docker context connected to a manager, or ask whoever operates the cluster for the right context. Do not run docker swarm init on a production host as a troubleshooting shortcut: that changes cluster state and is outside this inspection workflow.
3. Filter to one question
Use one --filter flag for a narrow query. The supported filters documented for this command are id, name, node and desired-state:
$ docker stack ps --filter "desired-state=running" STACK_NAME
$ docker stack ps --filter "node=NODE_NAME" STACK_NAME
$ docker stack ps --filter "name=SERVICE_NAME" STACK_NAME
$ docker stack ps --filter "id=TASK_ID_PREFIX" STACK_NAME
desired-state=runningshows tasks the scheduler wants running. It does not guarantee the current state is running, so read the current-state column too.- Documented desired states are
running,shutdown,readyandaccepted. - Repeated filter flags are combined as an OR in the current Docker documentation.
For example, this asks for tasks matching either of two names:
$ docker stack ps -f "name=SERVICE_NAME.1" -f "name=SERVICE_NAME.2" STACK_NAME
Tip
Quote each complete key=value expression. That keeps shell metacharacters and whitespace from changing what Docker receives.
4. Make the output script-friendly
Use --quiet when a later command only needs task IDs:
$ docker stack ps --quiet STACK_NAME
TASK_ID_1
TASK_ID_2
Warning
Do not pipe that output blindly into a destructive command. A task ID is an identifier, not confirmation that the task is safe to remove or alter. If you need details, inspect a selected ID deliberately with a separate command after reviewing the list.
For structured processing, use the built-in JSON format:
$ docker stack ps --format json STACK_NAME
{"CurrentState":"Running ...","DesiredState":"Running","Error":"","ID":"...","Image":"...","Name":"...","Node":"...","Ports":"..."}
Each task is emitted as a JSON object. Values and timestamps are cluster-specific, so parse the fields rather than matching the example text.
The command also accepts a Go template. This prints a compact name and image view without table headings:
$ docker stack ps --format '{{.Name}}: {{.Image}}' STACK_NAME
SERVICE_NAME.1: IMAGE_REFERENCE
5. Keep identifiers and image digests
Use --no-resolve when you need the underlying IDs instead of Docker's name mapping:
$ docker stack ps --no-resolve STACK_NAME
This helps when names are confusing across nodes, or when you are comparing against lower-level Docker information. Use --no-trunc when the shortened task ID, error text or image reference is not enough:
$ docker stack ps --no-trunc STACK_NAME
Long output is hard to scan. Start with the default table, filter the suspected task, then rerun with --no-trunc or --format json only when you need the extra detail.
6. Diagnose failures without changing the cluster
A missing stack name is a local command error:
$ docker stack ps
docker: 'docker stack ps' requires 1 argument
A plausible name is not enough if the daemon is not connected to a manager. On a non-manager node, the installed CLI reports an error such as:
$ docker stack ps STACK_NAME
Error response from daemon: This node is not a swarm manager.
Check the active context and daemon connection before trying elevated privileges:
$ docker context show
$ docker info
$ docker node ls
- Manager access.
docker node lsitself needs a manager, so a failure there is useful evidence, not a reason to initialise a new Swarm. - No rows match. If the stack exists, remove filters and check the exact stack name.
- A task shows an error. Preserve the full output with
--no-truncbefore changing a service or redeploying it.
7. Finish with an explicit check
For a routine health review, capture a filtered list and then verify that the result is not empty:
$ docker stack ps --filter "desired-state=running" --format '{{.Name}} {{.CurrentState}} {{.Error}}' STACK_NAME
$ docker stack ps --filter "desired-state=running" -q STACK_NAME | wc -l
Checkpoint
The count is only a count of matching tasks. Compare it with the service's intended replica count, and inspect current state and error fields before declaring the stack healthy.
Done means
- Command confirmed. You checked the installed Docker CLI and its
docker stack pssyntax. - Right target. You ran the query against the correct stack on a Swarm manager.
- Filtering works. You can filter by task ID, name, node or desired state.
- Output chosen. You know when to use quiet, JSON, templates,
--no-resolveand--no-trunc. - Health checked properly. You looked at current state and error text instead of treating a task row as proof of health.
- Cluster untouched. You have not initialised a Swarm, redeployed a service or altered cluster state.