What's Actually Happening
Jenkins pipeline input steps timeout when waiting for manual approval. The pipeline fails or proceeds with default action after timeout expires.
The Error You'll See
Input timeout in logs:
[Pipeline] input
Waiting for approval...
Input requested: Deploy to production?
Timeout expired after 30 minutes
Proceeding with default action: 'Abort'Pipeline aborted:
org.jenkinsci.plugins.workflow.steps.input.InputStepExecution$TimeoutExpiredException: Input timed outBuild failed:
```bash $ curl -s http://jenkins:8080/job/my-job/123/consoleText
ERROR: Input step timed out after 30m Build aborted ```
Why This Happens
- 1.Timeout too short - Approval takes longer than configured
- 2.Approver unavailable - No one available to approve
- 3.Wrong timeout unit - Minutes vs seconds confusion
- 4.No default action - Timeout without fallback
- 5.Build executor blocked - Executor held during input wait
- 6.Approval permissions - Approver lacks permissions
Step 1: Check Input Configuration
```groovy // In pipeline script: input message: 'Deploy to production?', submitter: 'admin,release-team', submitterParameter: 'approver', parameters: [ string(name: 'environment', defaultValue: 'prod') ]
// Check timeout configuration: input message: 'Approve deployment?', timeout: 30, // Default: unit depends on context timeoutUnit: 'MINUTES'
// View in Jenkins: # Job > Build > Console Output # Shows input configuration ```
Step 2: Adjust Timeout Settings
```groovy // Increase timeout: input message: 'Deploy to production?', timeout: 60, timeoutUnit: 'MINUTES'
// Or use SECONDS: input message: 'Quick approval needed', timeout: 300, timeoutUnit: 'SECONDS'
// Or use HOURS for long processes: input message: 'Security review required', timeout: 4, timeoutUnit: 'HOURS'
// No timeout (wait indefinitely): input message: 'Waiting for approval' // No timeout parameter
// In Jenkinsfile: pipeline { agent any stages { stage('Approval') { input { message "Deploy to production?" ok "Deploy" timeout(time: 60, unit: 'MINUTES') submitter "admin,release-team" } steps { sh 'deploy.sh' } } } } ```
Step 3: Configure Default Action
```groovy // Set default action on timeout: input message: 'Deploy to production?', timeout: 30, timeoutUnit: 'MINUTES', ok: 'Proceed', // Button to proceed submitter: 'admin'
// Handle timeout in script: try { timeout(time: 30, unit: 'MINUTES') { input message: 'Approve deployment?', submitter: 'admin' } // Approved - proceed with deployment sh 'deploy.sh' } catch (org.jenkinsci.plugins.workflow.steps.input.InputAbortedException e) { echo 'Input aborted or timed out' // Handle abort sh 'cleanup.sh' }
// Or use proceed parameter: input message: 'Deploy?', timeout: 30, timeoutUnit: 'MINUTES', submitter: 'admin', ok: 'Deploy', abort: 'Skip' // Button to abort ```
Step 4: Check Approver Permissions
```bash # Check who can approve curl -s http://jenkins:8080/job/my-job/config | grep submitter
# In Jenkins UI: # Manage Jenkins > Manage Roles (if Role Strategy plugin) # Or: Job > Configure > Build Triggers
# Check user permissions: curl -s http://jenkins:8080/user/admin/api/json | jq '.id'
# Approver must have: # - Job build permission # - Input submit permission
# In pipeline, specify approvers: input message: 'Deploy?', submitter: 'admin,release-team', // User IDs or groups submitterParameter: 'approver' // Capture who approved
# Check approver list: curl -s "http://jenkins:8080/job/my-job/123/input" | jq '.proceedText' ```
Step 5: Handle Executor Blocking
```groovy // Input step blocks executor by default // Use 'wait: false' to not block:
input message: 'Approve deployment?', submitter: 'admin', wait: false // Don't block executor
// This creates a separate task for approval // Pipeline continues without blocking executor
// Or use milestone to prevent parallel: milestone label: 'Before approval' input message: 'Approve?' milestone label: 'After approval'
// Check executor usage: curl -s http://jenkins:8080/computer/api/json | jq '.busyExecutors' ```
Step 6: Check Build Logs
```bash # View build console: curl -s http://jenkins:8080/job/my-job/123/consoleText
# Check for timeout messages: curl -s http://jenkins:8080/job/my-job/123/consoleText | grep -i timeout
# Look for: # - "Timeout expired" # - "Input requested" # - "Waiting for approval"
# Check Jenkins logs: cat /var/log/jenkins/jenkins.log | grep -i input
# Or journalctl: journalctl -u jenkins | grep -i "input|timeout"
# Check waiting builds: curl -s http://jenkins:8080/job/my-job/api/json?tree=builds[number,result,actions[waitingInput]] | jq '.builds[] | select(.actions[].waitingInput)' ```
Step 7: Approve Via API
```bash # If timeout approaching, approve via API:
# Check if input waiting: curl -s http://jenkins:8080/job/my-job/123/input
# Get input ID: curl -s http://jenkins:8080/job/my-job/123/input/id
# Approve: curl -X POST http://jenkins:8080/job/my-job/123/input/proceed \ -u "admin:api-token" \ -H "Content-Type: application/json" \ -d '{"environment": "prod"}'
# Or abort: curl -X POST http://jenkins:8080/job/my-job/123/input/abort \ -u "admin:api-token"
# Check approval status: curl -s http://jenkins:8080/job/my-job/123/api/json | jq '.result' ```
Step 8: Configure Email Notifications
```groovy // Send email when waiting for approval: emailext subject: "Approval needed for ${env.JOB_NAME} #${env.BUILD_NUMBER}", body: "Pipeline waiting for your approval.\n\n${env.BUILD_URL}input", to: 'release-team@example.com'
input message: 'Deploy to production?', submitter: 'admin,release-team'
// Send timeout notification: try { timeout(time: 30, unit: 'MINUTES') { emailext subject: "Approval needed", body: "Waiting for approval. Will timeout in 30 minutes.", to: 'release-team@example.com' input message: 'Approve?', submitter: 'admin' } } catch (Exception e) { emailext subject: "Approval timeout", body: "Pipeline timed out waiting for approval", to: 'release-team@example.com' } ```
Step 9: Use Conditional Logic
```groovy // Handle approval result: def approval = input message: 'Deploy?', submitter: 'admin', parameters: [ choice(name: 'action', choices: ['deploy', 'skip', 'rollback'], description: 'Choose action') ]
switch(approval.action) { case 'deploy': sh 'deploy.sh' break case 'skip': echo 'Skipping deployment' break case 'rollback': sh 'rollback.sh' break }
// Or capture approver: def result = input message: 'Approve?', submitter: 'admin,release-team', submitterParameter: 'approver'
echo "Approved by: ${result.approver}" ```
Step 10: Monitor Input Steps
```groovy // Create approval tracking: pipeline { agent any stages { stage('Approval') { steps { script { def startTime = System.currentTimeMillis() try { timeout(time: 30, unit: 'MINUTES') { input message: 'Approve?', submitter: 'admin' } def duration = (System.currentTimeMillis() - startTime) / 1000 / 60 echo "Approval took ${duration} minutes" } catch (Exception e) { def duration = (System.currentTimeMillis() - startTime) / 1000 / 60 echo "Timed out after ${duration} minutes" currentBuild.result = 'ABORTED' } } } } } }
// Track in metrics: // Use Prometheus plugin to track approval durations ```
Jenkins Pipeline Approval Checklist
| Check | Location | Expected |
|---|---|---|
| Timeout value | input step | Sufficient for approval |
| Timeout unit | input step | Correct (MINUTES/HOURS) |
| Approver list | submitter | Valid users/groups |
| Permissions | Role Strategy | Build + Input permission |
| Default action | input step | Handle timeout gracefully |
| Executor block | wait parameter | Avoid blocking |
Verify the Fix
```bash # After adjusting timeout
# 1. Run pipeline with approval # Job > Build with Parameters
# 2. Check input waiting curl -s http://jenkins:8080/job/my-job/123/input // Input waiting for approval
# 3. Wait extended time (60 minutes) # No timeout error
# 4. Approve via UI or API curl -X POST http://jenkins:8080/job/my-job/123/input/proceed // Proceeded successfully
# 5. Check build result curl -s http://jenkins:8080/job/my-job/123/api/json | jq '.result' // SUCCESS
# 6. Review approval log curl -s http://jenkins:8080/job/my-job/123/consoleText | grep -i approved // Approved by: admin ```
Related Issues
- [Fix Jenkins Build Queue Stuck](/articles/fix-jenkins-build-queue-stuck)
- [Fix Jenkins Pipeline SCM Checkout Failed](/articles/fix-jenkins-pipeline-scm-checkout-failed)
- [Fix Jenkins Agent Offline](/articles/fix-jenkins-agent-offline)