1. Introduction
A Jenkins pipeline that hangs — showing "running" in the UI but producing no log output and never completing — is one of the most frustrating CI/CD problems. Unlike a clean failure with an error message, a stuck pipeline occupies an executor indefinitely, blocks other builds from running, and gives you nothing to work with except the knowledge that something is waiting for something else.
This guide covers the most common causes of stuck Jenkins pipelines and how to diagnose and fix each one. For general pipeline failures that do produce an error, see Fix CI/CD Pipeline Failed.
2. What "Stuck" Means for Jenkins
A Jenkins pipeline hangs when a step starts executing and never exits — either because it's waiting for external input, waiting for a resource that never becomes available, or executing a process that ignores termination signals. Jenkins keeps the executor reserved and the build in "running" state until the pipeline either completes, is aborted manually, or times out (if a timeout is configured).
3. Common Causes
- A shell command is waiting for user input (interactive prompt not suppressed)
inputstep in a Declarative Pipeline waiting for approval that never comeskubectl rollout statusorkubectl waitwithout a timeout- An SSH command waiting for host key verification
- A test process hung on a deadlock or infinite loop
- A background process launched in a script that Jenkins is waiting to finish
- A Docker container run without
--rmthat didn't exit cleanly - Waiting for a lock that another stuck or failed build holds
- Network call to an external service that never returns
4. Step-by-Step Diagnosis and Fix
Step 1: Identify where the pipeline is stuck
# In the Jenkins UI:
# 1. Click on the running build
# 2. Click "Pipeline Steps" (for Declarative pipelines)
# 3. The currently executing step is the one that's hung
# OR
# Click "Console Output" and see what the last log line was
# From the Jenkins agent host (if you have SSH access):
# Find the process that Jenkins is waiting for
ps aux | grep -E "npm|python|docker|kubectl|ssh" | grep -v grep
# Or find Jenkins agent processes specifically
ps aux | grep jenkins | grep -v grep
Step 2: Fix interactive prompts in scripts
The most common cause: a command waiting for y/n input that will never arrive in CI.
# Common commands that prompt for input — and their non-interactive flags:
# Package managers:
apt-get install -y package # -y suppresses confirmation
yum install -y package
pip install --no-input package
# Terraform:
terraform apply -auto-approve
terraform destroy -auto-approve
# SSH (host key verification):
ssh -o StrictHostKeyChecking=no -o BatchMode=yes user@host command
# Docker (when running containers that ask for input):
echo "y" | docker exec -i container-name some-command
# or use: docker exec -i container-name sh -c "echo y | command"
Step 3: Add timeouts to all waiting commands
# kubectl rollout status ALWAYS needs a timeout
kubectl rollout status deployment/my-app --timeout=5m
# kubectl wait also needs a timeout
kubectl wait --for=condition=Available deployment/my-app --timeout=3m
# Wrap an entire stage in a Jenkins timeout:
stage('Deploy') {
options {
timeout(time: 10, unit: 'MINUTES')
}
steps {
sh 'kubectl apply -f manifests/'
sh 'kubectl rollout status deployment/my-app --timeout=8m'
}
}
# Global pipeline timeout (catches anything that hangs):
pipeline {
options {
timeout(time: 1, unit: 'HOURS')
}
...
}
Step 4: Fix stuck input steps
# A pipeline with an input step waiting indefinitely:
stage('Approve') {
steps {
input message: 'Deploy to production?', ok: 'Deploy'
}
}
# Fix: wrap with a timeout so it auto-aborts if not approved
stage('Approve') {
options {
timeout(time: 30, unit: 'MINUTES')
}
steps {
input message: 'Deploy to production?', ok: 'Deploy'
}
}
# Or abort pending input from the Jenkins Script Console (Manage Jenkins → Script Console):
Jenkins.instance.getItemByFullName('my-pipeline')
.getBuildByNumber(42)
.getAction(org.jenkinsci.plugins.workflow.support.steps.input.InputAction.class)
.getExecutions()
.each { it.proceed('') }
Step 5: Kill a stuck build and its child processes
# In Jenkins UI: Build → Abort (stop icon)
# If that doesn't work after 30 seconds, kill from the agent:
# Find the PID of the stuck command (on the agent host)
ps aux | grep "my-hanging-command"
# Kill it
kill -9 <PID>
# Jenkins should then mark the build as aborted
# If Jenkins itself appears frozen, restart just the agent:
# Jenkins → Manage Jenkins → Manage Nodes → <node> → Disconnect/Reconnect
# Using Jenkins Script Console to abort a specific build:
Jenkins.instance.getItemByFullName('my-job').getBuildByNumber(42).doStop()
Step 6: Fix background processes that prevent build completion
# A script that starts a background process can prevent Jenkins from completing
# the build because it waits for all child processes to exit.
# Wrong: starts background process, Jenkins waits for it forever
sh 'nohup ./server.sh &'
# Fix: disown the process so Jenkins doesn't track it
sh 'nohup ./server.sh & disown'
# Or for integration tests: start, run tests, stop
sh '''
./server.sh &
SERVER_PID=$!
sleep 5 # wait for startup
npm run test:integration
kill $SERVER_PID
'''
5. Verification Steps
# After fixing, re-run the pipeline and monitor:
# 1. The previously-stuck stage should complete within its timeout
# 2. No executor should remain in "Running" state after the pipeline ends
# Check that no lingering processes are left on the agent
ps aux | grep -E "your-hanging-command" | grep -v grep
# Should return no results after the build completes
6. Common Mistakes
- Not adding a timeout at the pipeline level — any stuck step will hang indefinitely
- Using
sh 'command &'withoutdisown— Jenkins tracks all child PIDs and waits for them - Running
docker exec -itwith-tflag — allocates a pseudo-TTY which waits for terminal input - Forgetting
--timeoutonkubectl rollout status— if a deployment fails to roll out, this hangs forever - Input steps without timeouts in automated deployment pipelines — an unanswered approval request blocks all downstream builds
7. Prevention Tips
- Add a global pipeline timeout as standard in every Jenkinsfile:
options { timeout(time: 1, unit: 'HOURS') } - Add stage-level timeouts for any stage that calls an external service or runs a deployment
- Use the Lockable Resources plugin instead of manual locking if you need to prevent parallel builds accessing shared resources
- Test all shell scripts locally with
bash -x script.shand check they exit cleanly without interactive prompts - Monitor executor utilisation — if all executors are always busy, you may have stuck builds that need investigating
- See Fix Environment Variables Not Working — missing env vars can cause commands to prompt for credentials that never arrive
8. FAQ
The "Abort" button in the UI doesn't stop the build. Why?
The stuck process is ignoring SIGTERM. Jenkins sends SIGTERM to the build process when you abort, but some processes (particularly Java processes, Docker containers, or processes that trap signals) ignore it. You'll need to kill the process directly on the agent host using kill -9 <PID>, or kill the Docker container if the build runs in one.
How do I prevent stuck builds from blocking my executor pool?
Add a global timeout in every Jenkinsfile: options { timeout(time: 2, unit: 'HOURS') }. This ensures no build can hold an executor longer than 2 hours regardless of what's hanging. Also consider configuring the Jenkins "Build Discarder" plugin to auto-abort builds that exceed your maximum expected duration.
9. Summary
| Symptom | Cause | Fix |
|---|---|---|
| Pipeline hangs on shell command | Interactive prompt waiting for input | Add -y, --yes, or --non-interactive flags |
| Hangs on kubectl rollout status | No --timeout flag | Add --timeout=5m to the command |
| Hangs on input step | Approval request never answered | Wrap with timeout(time: 30, unit: 'MINUTES') |
| Build completes in Jenkins but executor stays busy | Background process not disowned | Use & disown or kill PID explicitly |
| Abort button doesn't work | Process ignoring SIGTERM | kill -9 from agent host; kill Docker container |
Explore More in This Category
Explore more in this category: CI/CD guides. Browse all DevOps Compass articles or jump to: Kubernetes, AWS, CI/CD, Containers, Monitoring, Networking.