Chapter 10Lesson 04~125 minutes

Declarative Pipeline Syntax, agent, stages, steps, options, parameters, environment, tools, and post: Diagnostics, Failure Modes, Security, and Performance

Diagnose Declarative failures by separating model validation, queue/agent allocation, tool/workspace execution, credentials, post conditions, and external state while preserving first-failure evidence.

DiagnosticsSecurityValidationCapacitySecretsFailure evidence

Learning objectives

  • Recognize a Declarative model-validation failure before investigating agents or shell commands.
  • Prevent expensive agents from being held during human input waits.
  • Explain why credential masking is not a complete secret-isolation mechanism.
  • Design post conditions that do not assume unavailable workspaces.
  • Use an evidence-first sequence and smallest safe repair instead of broad restarts/retries.

1. Diagnose the layer, not the symptom

Declarative Pipeline gives you an extra failure layer before ordinary Pipeline runtime: model validation. Preserve the failing source SHA and first error before changing anything. Then move down the lifecycle only as evidence demands.

Evidence-first diagnostic ladder
flowchart TD
 A[Source SHA + Jenkinsfile] --> B{Declarative model valid?}
 B -->|no| C[Fix directive / scope only]
 B -->|yes| D[Queue + label + executor]
 D --> E[Agent / workspace / tools]
 E --> F[Pipeline step / shell / tests]
 F --> G[Credentials / network / external service]
 G --> H[Reports / artifacts / publication]
 H --> I[post conditions + final result]
 I --> J[Smallest safe retry / rerun]

2. Failure mode: directive in the wrong scope

Intentionally broken example:

pipeline {
  agent any
  stages {
    stage('Broken') {
      parameters {
        string(name: 'TARGET', defaultValue: 'sandbox')
      }
      steps { echo 'never reaches runtime' }
    }
  }
}

parameters belongs at the top level, so Declarative model validation should reject this structure. Preserve the validation message and Jenkinsfile SHA. Do not restart the agent, reinstall Git, or delete the workspace: none of those layers has been reached.

Repair: move parameters back to the top-level pipeline block, commit a new revision, and validate again. Change one causal variable at a time.

3. Failure mode: holding an expensive agent during approval

This shape acquires the stage's agent before it reaches the input step:

stage('Approve') {
  agent { label 'expensive-lab-agent' }
  steps {
    input message: 'Continue?'
    sh './bounded-action.sh'
  }
}

For long human waits, prefer a stage-level input directive so approval occurs before the agent is entered:

stage('Approve') {
  input { message 'Continue?' }
  agent { label 'expensive-lab-agent' }
  steps { sh './bounded-action.sh' }
}

Evidence is executor occupancy/queue behavior, not just elapsed wall time.

4. Failure mode: credentials exposed by interpolation/logging

Credentials Binding can mask recognized secret values, but masking cannot make careless command construction safe. Avoid Groovy interpolation of secrets into command strings, debug dumps of the environment, generated files with secrets, or tools that echo command-line arguments.

environment {
  LAB_TOKEN = credentials('ch10-fake-token')
}
stages {
  stage('Use secret safely') {
    agent { label 'lab-linux' }
    steps {
      sh '''
        set +x
        # The shell expands LAB_TOKEN; do not print it.
        test -n "$LAB_TOKEN"
        printf 'credential-present=yes\n'
      '''
    }
  }
}

The credential ID may be recorded as configuration evidence; the credential value must not be. Use only fake/disposable credentials in this lab.

5. Failure mode: post assumes a workspace that does not exist

With top-level agent none, a Pipeline-level post block has no guaranteed global workspace. Also, agent loss can make a previously used workspace unavailable. This is brittle:

pipeline {
  agent none
  stages {
    stage('Build') {
      agent { label 'lab-linux' }
      steps { sh 'echo ok > result.txt' }
    }
  }
  post {
    always {
      archiveArtifacts artifacts: 'result.txt'
    }
  }
}

Archive stage-owned evidence in a stage-level post or steps while that execution context exists, or explicitly allocate a node and transfer required data. Do not assume accidental workspace persistence.

6. Validation passed, but the stage never starts

A valid Declarative model can still wait forever because no online node matches the stage label, executors are saturated, or a cloud/ephemeral agent failed to provision. Preserve the queue reason. The correct evidence is the queue item, requested label, online nodes, and executor availability—not another syntax edit.

7. Tool resolution failure

If tools { maven 'maven-3.9' } is valid but the build fails resolving/installing the tool, inspect the Jenkins tool definition, plugin/provider involved, agent OS/architecture, filesystem permissions, and network requirements. Do not confuse the Java that runs Jenkins with the build JDK selected for a stage.

8. Performance: controller logic and executor occupancy

  • Keep heavy computation/file/network work in agent-side tools rather than Groovy loops in script.
  • Use agent none and stage agents when it meaningfully reduces idle executor time.
  • Use stage-level input for long approvals before expensive allocation.
  • Keep retries narrow so failures do not multiply resource use.
  • Use sensible build-retention policy; evidence is valuable but unbounded retention consumes controller storage.

9. Evidence-first diagnostic sequence

  1. Preserve job/build/queue IDs, source/Jenkinsfile SHA, and the first validation/runtime error.
  2. Confirm Jenkins core, Java, Pipeline, Declarative, and relevant plugin baseline.
  3. Confirm the Pipeline job configuration, trigger cause, parameters, and source revision.
  4. Determine whether failure occurred during model validation, before any queue item.
  5. If runtime started, inspect queue reason, requested label, node/executor, workspace, and tools.
  6. Inspect Pipeline step/shell/test evidence.
  7. Inspect credential binding, network, and external service only if the failure reached those layers.
  8. Inspect reports/artifacts/publication separately from step success.
  9. Apply the least destructive correction.
  10. Retry/rerun only the smallest safe scope after checking external side effects.

10. Shortcuts that are not repairs

Do not disable CSRF/TLS/authorization/Script Security, print secrets for debugging, run untrusted work on the controller, use broad admin credentials, turn off SSH host-key checking, blindly retry publication/deployment, delete jobs/workspaces as the first diagnostic step, or increase executors without capacity analysis.

11. Minimal incident packet

Save the Jenkinsfile SHA, validation error or first stack/console failure, build URL/number, cause, non-secret parameters, queue item/reason, node/label/workspace, installed Pipeline/Declarative versions, tool versions, relevant archived evidence, and any externally verified target state. Record what you changed and the repairing source revision.

Next lesson

Checkpoint Lab — Declarative Pipeline

Author a complete multi-stage Declarative Jenkinsfile, predict state changes, validate it, break one directive intentionally, repair it narrowly, and prove final stage/build evidence.

Knowledge check

A Jenkinsfile fails because parameters is inside a stage. Which layer failed?

How can you avoid holding an expensive agent while waiting for approval?

Does secret masking make it safe to echo or interpolate credentials?

Why can Pipeline-level post be unsafe for workspace assumptions under agent none?

What should happen before retrying a failed external side-effect step?

Official references and version notes

Version and compatibility note

Rechecked on 2026-09-16. Examples assume Jenkins 2.568.3 LTS, tested with Java 21 and 25, Pipeline aggregator 608.v67378e9d3db_1, Pipeline: Declarative 2.2293.v6e7193cec599, Credentials Binding 728.v902a_273b_8947, and optional Stage View 2.41. Declarative 2.2293 requires Jenkins 2.504.3 or newer. Labs reuse the Chapter 08 tool names jdk21-build and maven-3.9; verify what exact binaries those names resolve to on your disposable agent before running. Plugin versions and supported directives change independently, so capture the installed baseline rather than assuming these versions forever.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.