Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read Last reviewed Jul 2026

Docker Error Guide: 'no suitable node (scheduling constraints not satisfiable)' Swarm Service Stuck

Quick answer

Fix Docker Swarm's 'no suitable node (scheduling constraints not satisfiable)' error: diagnose placement constraints, missing node labels, and unavailable CPU/memory resources.

  • #docker
  • #troubleshooting
  • #errors
  • #swarm
Free toolkit

Stuck on this Docker with AI error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Exact Error Message

$ docker service ps web
ID             NAME    IMAGE          NODE   DESIRED STATE   CURRENT STATE            ERROR                              PORTS
q1w2e3r4t5y6   web.1            nginx:latest          Pending   Pending 12 seconds ago   "no suitable node (scheduling …"

Expanding the error with --no-trunc reveals the full message:

"no suitable node (scheduling constraints not satisfiable on 3 nodes)"

You may also see variants such as no suitable node (insufficient resources on 3 nodes) or no suitable node (1 node not available for new tasks), all describing the same class of scheduling failure.

What It Means

Docker Swarm’s scheduler could not find any node in the cluster that satisfies every requirement of the service task. The service is accepted and its desired state is running, but the task stays Pending because no node passes all the filters the scheduler applies: placement constraints, placement preferences, resource reservations, and node availability.

This is a scheduling decision, not a container crash. The image is never pulled and no container is created, because Swarm will not place a task on a node that does not qualify. The most common trigger is a placement constraint that references a label no node carries.

Common Causes

  • A --constraint references a node label (for example node.labels.tier == web) that no node actually has.
  • A constraint targets a role or hostname that does not exist, such as node.role == worker in a manager-only cluster.
  • Resource reservations (--reserve-memory / --reserve-cpu) exceed what any node has free.
  • All matching nodes are Drain or Pause, so they are unavailable for new tasks.
  • A --placement-pref combined with a hard constraint leaves no eligible node.
  • Label typos or case mismatches between the constraint and the node label.

Diagnostic Commands

Read the full, untruncated scheduling error:

docker service ps web --no-trunc

Inspect the constraints and reservations the service actually requests:

docker service inspect web --format '{{json .Spec.TaskTemplate.Placement}}'
docker service inspect web --format '{{json .Spec.TaskTemplate.Resources}}'

List nodes and confirm their availability and role:

docker node ls

Check the labels on a specific node the constraint should match:

docker node inspect worker-01 --format '{{json .Spec.Labels}}'

Step-by-Step Resolution

  1. Get the exact constraint. Run docker service inspect web --format '{{json .Spec.TaskTemplate.Placement}}' and note every constraint string. This tells you precisely what the scheduler is filtering on.

  2. Verify the label exists on at least one node. If the constraint is node.labels.tier == web, confirm a node carries that label:

docker node inspect worker-01 --format '{{index .Spec.Labels "tier"}}'
  1. Add the missing label to the intended node if it is absent:
docker node update --label-add tier=web worker-01
  1. Fix availability. If matching nodes show Drain under docker node ls, return them to active so they can accept tasks:
docker node update --availability active worker-01
  1. Right-size reservations. If the failure is insufficient resources, lower the reservation or move it to a larger node:
docker service update --reserve-memory 256M web
  1. Correct or remove a bad constraint on the running service without redeploying the stack:
docker service update --constraint-rm 'node.labels.tier==web' web
docker service update --constraint-add 'node.role==worker' web
  1. Confirm the task schedules. The state should move from Pending to Running:
docker service ps web
web.1   nginx:latest   worker-01   Running   Running 4 seconds ago

Prevention

  • Apply node labels as part of cluster provisioning so constraints always have a target, and document which labels each service depends on.
  • Keep constraint strings in version-controlled Compose/stack files rather than ad hoc docker service create flags, so label expectations are reviewable.
  • Match label case and spelling exactly; Tier and tier are different keys to the scheduler.
  • Set resource reservations based on real node capacity, and size the cluster so at least one node can host each service’s reservation with headroom.
  • Before draining a node for maintenance, confirm remaining active nodes still satisfy every constraint, or tasks will pile up as Pending.
  • Test placement changes on one service with docker service update before rolling them into a full stack deploy.
  • no suitable node (insufficient resources on N nodes) — reservations exceed free CPU/memory rather than a label mismatch.
  • no suitable node (max replicas per node reached) — a max_replicas_per_node limit blocks further placement.
  • rejected: node is missing network attachments — a networking issue, not a constraint filter.
  • task: non-zero exit — the container did schedule but crashed, which is a different problem.

Frequently Asked Questions

Why is my task stuck in Pending instead of failing? Swarm keeps the task in Pending because the desired state is still running; it will schedule the moment a qualifying node appears. It never gives up, so a constraint that can never match leaves the task pending indefinitely.

How do I see the real reason behind the truncated message? Run docker service ps <service> --no-trunc. The default output clips the error; the untruncated form shows whether it is constraints, resources, or availability.

Do I need to redeploy the whole stack to fix a constraint? No. docker service update --constraint-rm and --constraint-add adjust placement on the live service, and adding a node label with docker node update --label-add can fix it without touching the service at all.

Can placement preferences alone cause this? A preference (--placement-pref) only spreads tasks and will not block scheduling by itself, but combined with a hard constraint it can leave no eligible node. Check both under the Placement spec.

Where can I learn more Docker Swarm patterns? Generate targeted diagnostics and fix steps with the DevOps AI prompt library, and browse more Docker guides.

Free download · 368-page PDF

Fixed it? Get 500 Docker with AI & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.