What executor starvation means
Every Jenkins task runs on an executor — a slot for execution, effectively a thread on a node. The number of executors on a node sets how many tasks it can run concurrently (Managing nodes). When all executors on every node that can run a given job are busy or unavailable, builds pile up in the queue. Jenkins marks a starved item with a clock icon in the build queue, and the tooltip gives the reason (Executor starvation).
Two distinctions decide everything that follows:
- Starved vs blocked. A starved item is ready to run but has no free slot. A blocked item has free slots available but is held back by a rule — a throttle category, a quiet period, or a block-on-upstream/downstream setting. The queue reason string tells you which.
- Heavyweight vs flyweight. A Pipeline job's top level runs on a flyweight
executor that does not consume a configured slot; only its
node {}block takes a heavyweight slot. A Pipeline can read as "running" while itsnodestep is the thing stuck in the queue.
Diagnose it
The build queue and node state tell most of the story. From the UI, open Manage Jenkins → Nodes and the Build Queue. From the Script Console (Manage Jenkins → Script Console) you can list exactly what is holding slots and why each item waits:
// Queued items and the exact block/wait reason for each
Jenkins.instance.queue.items.each { item ->
println "${item.task.name} -> ${item.why}"
}
// Per-node executor usage and online state
Jenkins.instance.computers.each { c ->
println "${c.displayName} online=${!c.offline} " +
"busy=${c.countBusy()}/${c.numExecutors} " +
"offlineCause=${c.offlineCause}"
}
// Currently running builds, to spot a hung one holding a slot
Jenkins.instance.computers*.executors.flatten().findAll { it.isBusy() }.each { e ->
println "${e.currentExecutable} running for ${e.elapsedTime}ms"
}
The queue item reason is the fastest signal. "Waiting for next available executor" or the clock icon means a real slot shortage; "there are no nodes with the label '...'" means a label mismatch, not capacity; a reason naming a throttle category, a quiet period, or an upstream/downstream block means the item is blocked, not starved, and adding executors will not help.
Causes, each end to end
Genuine capacity shortage
More concurrent builds than total executors across eligible online nodes.
- Diagnose: queue reason is "Waiting for next available executor" (clock
icon); the per-node script shows
busy == numExecutorson every eligible node. - Fix: when all agents with a given label are fully busy, add more agents (Executor starvation). Prefer adding agents over piling executors onto one node — one executor per node is the safest configuration, and one per CPU core only works for small tasks (Managing nodes).
Hung or long-running builds holding a slot
A build blocked on input, a deadlocked test, or a stuck external call holds its executor indefinitely.
- Diagnose: the running-builds script shows an executable whose
elapsedTimefar exceeds its historical duration. - Fix: abort the hung build to free its executor immediately, then address the root hang (input timeout, test deadlock, external-call timeout).
Offline agents (lost connection or auto-offline)
An agent's executors leave the pool when the agent goes offline. This includes agents that lost connectivity and agents Jenkins took offline automatically: node monitors mark a node offline when free disk, temp space, swap, clock difference, or response time crosses the configured threshold (Managing nodes).
- Diagnose: the per-node script shows
online=false;offlineCausenames the reason. Or visithttp://SERVER/jenkins/computer/AGENTNAMEto see the offline status (Executor starvation). - Fix: reconnect the agent or clear the monitor condition (free disk, fix the clock). To stop one offline node from starving jobs, de-couple builds from specific agents and target labels instead, so a build can run on any qualifying machine (Executor starvation).
Label mismatch or usage restriction
A job pinned to a label runs only on agents carrying that label. Separately, a node set to Only build jobs with label expressions matching this node will not pick up unlabeled jobs even when idle, whereas Use this node as much as possible lets it take any job (Using Jenkins agents).
- Diagnose: queue reason reads "there are no nodes with the label '...'". Compare the job's Restrict where this project can be run label expression against the agents' labels and usage mode.
- Fix: relabel an online agent, relax the job's node restriction, or switch the node's usage to "Use this node as much as possible."
Flyweight Pipeline waiting on a heavyweight slot
A Pipeline's top level runs on a flyweight executor that does not consume a
configured slot (Managing nodes);
its node {} block needs a real (heavyweight) slot. So a Pipeline can show as
running while its node step is queued. Nested parallel branches each take
their own node, multiplying demand.
- Diagnose: the job is "running" but the queue or its console shows it
waiting inside
node; the per-node script shows no free heavyweight slots on matching nodes. - Fix: treat it as a capacity or label problem for the agent labels the
nodesteps request — add agents/executors for those labels, or reduce the fan-out ofparallelbranches.
Built-in node executors set to 0
Running tasks on the built-in (controller) node is discouraged for security,
performance, and scalability reasons, and setting its executors to 0 is the
recommended configuration (Managing nodes).
The trap: a job with no label (or node {} with no agent) can only land on the
built-in node — so with 0 executors there it waits forever.
- Diagnose: queue reason points at the built-in node having no executors, while the job carries no label restriction.
- Fix: give the job a label that targets a real agent (do not re-enable controller executors as the fix).
Cloud / ephemeral agents still provisioning
With cloud plugins (EC2, Azure, and similar), agents are created on demand and destroyed when idle (Architecting for scale). A build can wait during spin-up, and an instance cap limits how many agents come up at once. An on-demand node that goes idle-offline also re-provisions cold.
- Diagnose: queue reason references provisioning/capacity for a cloud label; no static node carries that label yet.
- Fix: raise the cloud template's instance cap or pre-warm a minimum pool; expect a spin-up delay before the slot appears.
Blocked, not starved: throttle / quiet period / upstream-downstream
These hold an item in the queue while executors are free.
- Throttle Concurrent Builds: category limits (global, per-label, per-node) keep a task queued until the category frees up; if the category cannot be satisfied the task stays in the queue, and chains that consume all executors while waiting on downstream runs can deadlock (Throttle Concurrent Builds).
- Quiet period / block-on-upstream-or-downstream: a quiet period delays the start, and a block-on-dependency setting holds the job while a dependency is queued or building.
- Diagnose: queue reason names a throttle category, a quiet period, or an upstream/downstream block — not an executor.
- Fix: relax the throttle category or restructure chains to avoid the deadlock; shorten or skip the quiet period; remove the block-on-dependency rule if it is over-broad. Adding executors will not clear these.
Fix it (order of operations)
- Read each queued item's reason from the Script Console. Separate starved (waiting for executor / clock icon) from blocked (throttle, quiet period, upstream/downstream).
- For blocked items, fix the rule (throttle category, quiet period, block-on-dependency) — executors are not the problem.
- List nodes and executor usage; confirm which agents are online and how many
slots are actually busy. Check
offlineCausefor auto-offline conditions. - Abort any build running far past its historical duration to free a hung slot.
- Reconnect offline agents or clear the monitor condition that took them offline.
- For label mismatches, relabel an online agent, relax the job restriction, or change the node usage mode.
- For flyweight Pipelines, treat the
node-step labels as the capacity target. - Only after the above, add agents (preferred) or raise executors per node to lift sustained capacity.
How Intellira diagnoses this
Intellira queries the Jenkins MCP server for the build queue and per-node executor state, then reads each queued item's reason. It separates a true capacity shortage from a label mismatch, an offline agent, or a blocked item (throttle, quiet period, upstream/downstream), and flags any build holding an executor far beyond its historical duration as a likely hang. The output is a ranked cause — for example, an agent going offline and removing its executors while jobs targeting it starve — rather than a generic "builds are queued."
Sources
- Executor starvation — jenkins.io
- Managing nodes — jenkins.io
- Using Jenkins agents — jenkins.io
- Architecting for scale — jenkins.io
- Throttle Concurrent Builds plugin — plugins.jenkins.io
By Intellira Engineering. AI-assisted draft, reviewed by the Intellira engineering team; claims cited inline; last verified 2026-06-02.