Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Jenkins By James Joyner IV · · 9 min read

Jenkins Error: 'Cancelling nested steps due to timeout' / 'Pipeline aborted due to timeout' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Jenkins 'Cancelling nested steps due to timeout' / 'Timeout has been exceeded': scope timeout{} blocks, catch hung stages, split hangs from slow work.

  • #jenkins
  • #ci-cd
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

A timeout{} step or a job-level timeout fired: Jenkins gave a block of steps a deadline, the deadline passed, and Jenkins aborted the steps inside it. The console shows one of:

Cancelling nested steps due to timeout
Sending interrupt signal to process
Pipeline aborted due to timeout

or, for the activity-based variant:

Timeout set to expire in 1 hr 0 min without activity
Timeout has been exceeded

The build ends as ABORTED (grey), not FAILURE. The timeout is doing its job — the real question is whether the work genuinely hung (an agent wait, a stuck sh, an input nobody answered) or is just slower than the deadline you set.

Symptoms

  • The build status is ABORTED and the log shows Cancelling nested steps due to timeout followed by Sending interrupt signal to process.
  • A single stage (deploy, integration tests, a wait-for-agent) consistently trips the timeout while others finish.
  • With timeout(activity: true), the abort happens after a period of no log output, not after a fixed wall-clock duration.
  • An input step times out because no human approved it within its own timeout.
  • The job hangs waiting for an executor and the surrounding timeout fires before an agent frees up.
  • Raising the timeout “fixes” it sometimes but the same stage occasionally hangs forever without one.

Common Root Causes

  • Genuinely slow stage exceeding the deadline — the work legitimately takes longer than the timeout value (large build, big test suite) after growth over time.
  • A hung sh/subprocess — a child process waits on stdin, a lock, a dead network peer, or a prompt and never returns, so the block never completes.
  • Waiting for an executor/agent — the stage sits in the queue with no available executor; the wall-clock timeout fires while nothing is actually running.
  • Unanswered input step — a manual approval gate times out because no one responded within the input’s timeout.
  • Whole-pipeline timeout wrapping slow-but-fine stages — a single options { timeout() } covers the entire pipeline including legitimately long stages, so one slow stage aborts everything.
  • Activity vs absolute confusion — an absolute timeout is used where an activity timeout was intended (or vice versa), aborting healthy long-but-quiet work or missing a true hang that keeps printing.

How to diagnose

Find which block owns the timeout. The log line Cancelling nested steps due to timeout appears at the end of the timed block; the last real step before it is where the deadline was hit. In Blue Ocean, the timed-out stage is marked aborted.

Determine whether it hung or was merely slow. Compare the stage’s start time to its abort time against your timeout value, and check whether output was still flowing:

# On the agent while a suspect stage runs — is the sh child actually working or stuck?
ps -ef --forest | grep -A5 "durable-.*script.sh"
# Blocked on I/O / lock / network?
cat /proc/<pid>/status | grep -i State
ls -l /proc/<pid>/fd            # sockets/pipes it is waiting on

Check whether the build was queued (waiting for an executor) rather than running. In Manage Jenkins → Build Executor Status and the build’s log for Waiting for next available executor, confirm an agent was actually assigned.

For input timeouts, read the console for Input requested / Timeout expired and check the input step’s own timeout in the Jenkinsfile. Use the thread dump (https://jenkins.example.com/threadDump or Manage Jenkins → System Information) to see where a hung step is blocked.

Fixes

1. Wrap only the slow stage, not the whole pipeline

Scope the timeout tightly so one slow stage aborts itself without killing unrelated stages:

pipeline {
    agent any
    stages {
        stage('Build')  { steps { sh 'make build' } }          // no timeout needed
        stage('Integration Tests') {
            options { timeout(time: 30, unit: 'MINUTES') }      // scoped to this stage
            steps { sh 'make integration-test' }
        }
        stage('Deploy') {
            steps {
                timeout(time: 10, unit: 'MINUTES') {            // scoped block
                    sh './deploy.sh'
                }
            }
        }
    }
}

2. Use an activity timeout for long-but-noisy work

If a stage is legitimately long but continuously produces output, abort only when it goes silent (a real hang) rather than at a fixed wall-clock limit:

timeout(activity: true, time: 15, unit: 'MINUTES') {
    sh './long-running-but-chatty-task.sh'   // aborts only after 15 min of no output
}

3. Set a sane absolute cap at job level as a backstop

Keep a generous whole-pipeline timeout so a totally stuck build never runs forever, while per-stage timeouts catch specific hangs:

pipeline {
    agent any
    options {
        timeout(time: 2, unit: 'HOURS')   // absolute backstop for the whole run
    }
    // ... stages with their own tighter timeouts ...
}

4. Bound input gates so approvals don’t hang

Give manual approval a short timeout and treat expiry deliberately instead of failing loudly:

stage('Approve') {
    steps {
        script {
            try {
                timeout(time: 30, unit: 'MINUTES') {
                    input message: 'Deploy to production?', ok: 'Deploy'
                }
            } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
                echo 'Approval timed out — skipping deploy.'
                currentBuild.result = 'ABORTED'
            }
        }
    }
}

5. Fix the underlying hang or executor starvation

If the process genuinely hangs, address the root cause: add timeout/non-interactive flags to the child command (ssh -o BatchMode=yes, apt-get -y, terraform apply -input=false), avoid commands that read stdin, and ensure enough executors/agents so stages don’t sit in the queue until the wall-clock timeout fires. For chronic queue waits, see the executor-availability sibling below.

What to watch out for

  • A timeout block interrupts a step with a FlowInterruptedException — catch it explicitly if you need cleanup, otherwise the build aborts and skips your finally/post cleanup unless it’s in a post {} block.
  • Don’t just keep raising the timeout — an ever-growing deadline turns a real hang into hours of wasted executor time; investigate why it’s slow.
  • Absolute vs activity timeouts behave very differently: an absolute timeout kills healthy long work; an activity timeout misses a hang that keeps printing progress.
  • A job-level options { timeout() } covers post steps too — a slow post { always { … } } can itself be aborted.
  • Distinguish a genuine hang (thread dump shows blocked on I/O) from work that is simply slow before you tune deadlines. The free incident assistant at /dashboard/incident-response/ can help triage a stuck build fast.
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.