The Retry Step in Jenkins

The Retry Step in Jenkins

Some failures are just bad luck. Learn how the Jenkins retry step gives a pipeline a second chance, when that is wise, when it is dangerous, and how to design retries that make builds calmer instead of noisier.

You press the button on a coffee machine and nothing happens. You press it again, and the coffee flows. The machine was not broken. A tiny hiccup got in the way, and a second try solved it. Now imagine the machine is out of beans. Pressing the button ten more times will not help, and it may even damage the motor.

Software pipelines live with the same two kinds of trouble. Downloading a package can fail because the network blinked for one second. Compiling code can fail because a developer wrote a bug. The first kind deserves a retry. The second kind deserves a fix. The Jenkins retry step is the tool that presses the button again, and the skill lies in knowing when pressing is wise.

In this guide you will learn what the retry step does, how it counts attempts, how to combine it with timeouts and waiting, which failures to retry and which to leave alone, how it affects cost and safety, and which mistakes cause the most trouble. We assume you know nothing about Jenkins yet, and we explain each new word the first time it appears.

1What Is the Retry Step?

The retry step runs a piece of your pipeline again when it fails, up to a number of times that you choose.

First, the basics

Jenkins is a free automation server that builds, tests, and delivers software. A pipeline is a written list of steps that Jenkins follows, stored in a text file called a Jenkinsfile. A step is one action in that list, such as “download the dependencies” or “run the tests.” When a step fails, the pipeline normally stops, marks the build as failed, and tells the team.

What retry adds

The retry step is a wrapper. You put other steps inside it, and you tell it how many attempts are allowed. If the steps inside succeed, the pipeline moves on. If they fail, the retry step runs them again from the beginning. Only when the last allowed attempt fails does the failure escape and stop the pipeline.

The key word is “transient”

A transient failure is a problem that goes away by itself, such as a brief network outage, a busy server, or a temporary lock. A permanent failure is a problem that stays until someone fixes it, such as a syntax error or a wrong password. Retry is a good answer for the first kind and a poor answer for the second.

Everyday Analogy

Think of calling a friend and getting a busy signal. Calling again a minute later is sensible, because the line will probably be free. Calling a number that has been disconnected, ten times in a row, is pointless. The retry step is the redial button, and good judgement decides when to press it.

What it gives you

  • Fewer false alarms: one-second glitches no longer turn a build red.
  • Less human effort: nobody has to click “rebuild” and wait again.
  • Steadier pipelines: builds that depend on many outside systems become far more dependable.
Second chance
A short glitch does not fail the whole build
Limited
You choose the maximum number of attempts
Wrapper
It surrounds other steps and re-runs them
i
Remember

Retry does not fix problems. It waits for problems to go away. If the cause is permanent, retry only makes the failure slower and more expensive.

2Why It Exists: The Problem and the History

Modern builds depend on dozens of outside systems, and outside systems occasionally stumble.

The old world

In the early days of automation, a build usually ran on one machine and used files that were already there. There was little to go wrong. As software grew, builds began to download libraries from the internet, pull container images from registries, talk to cloud services, and reach test databases. Every one of those connections is a small chance of failure.

The mathematics of many small risks

Suppose each outside call succeeds 99.5 times out of 100. That sounds excellent. But a pipeline with fifty such calls succeeds every time only about 78 times out of 100. In other words, more than one build in five fails for reasons that have nothing to do with the code. Teams call this build noise, and it slowly destroys trust: people start ignoring red builds.

The Pipeline answer

When Jenkins moved to Pipeline as code around 2016, the community added a small set of control-flow steps, and retry was among the first. It was intentionally simple: run this block again if it fails. Over the years, it has gained refinements, such as the ability to retry only for certain kinds of infrastructure trouble, like the loss of a build machine.

Without retry

  • Every network blink turns a build red.
  • People click “rebuild” by hand, again and again.
  • Real failures hide among false alarms.

With sensible retry

  • Short glitches heal themselves.
  • Red builds mean something again.
  • Engineers spend time on real problems.
Everyday Analogy

A postal worker who finds nobody at home tries again later that day. Nobody would call that a failure of the postal system. Retrying is a normal part of any service that depends on other people or machines being ready.

Real-world motivation

Large technology companies that publish about reliability engineering describe retries as a basic building block of distributed systems, from web browsers to cloud storage clients. Build pipelines are distributed systems too, so the same lessons apply, including the warning that careless retries can cause more harm than the failures they hide.

3Core Concepts: The Words You Must Know

A handful of ideas explain almost everything about retrying well.

Count

Attempt

One run of the wrapped steps. The first run counts as attempt one, so a limit of three means one original try and at most two retries.

Failure

Transient failure

A problem that disappears on its own, such as a brief network error or a busy server. Good candidates for retry.

Failure

Permanent failure

A problem that stays until fixed, such as a compile error or a wrong password. Retrying it wastes time.

Safety

Idempotent

An action that is safe to repeat, because doing it twice leaves the same result as doing it once. Retry is safest around idempotent actions.

Wait

Backoff

Waiting between attempts, often for longer each time. It gives a struggling service room to recover.

Wait

Jitter

A small random change to the waiting time, so that many clients do not all retry at exactly the same moment.

Limit

Timeout

A maximum time for an attempt. Without it, a hung attempt never ends, and the retry never gets its turn.

Rule

Retry condition

A test that decides whether a failure is worth retrying, such as “only when the build machine was lost.”

Vocabulary table

WordMeaningExample
ExceptionThe signal a failing step raises to say something went wrongA download step reports a connection error
Flaky testA test that sometimes passes and sometimes fails on the same codeA timing-dependent web test
Rate limitA server’s cap on how many requests a client may makeA registry answering “too many requests”
Retry stormMany clients retrying at once and overwhelming a recovering serviceFifty builds all re-pulling an image together
Circuit breakerA rule that stops trying a service that keeps failingSkip the mirror after five straight failures
i
Good to know

The retry step does not itself wait between attempts. If you want a pause, you add one yourself. This is one of the most important facts in the whole guide, and later chapters show how to handle it.

4Architecture and Where Retry Sits

Retry is not a service or a plugin you install. It is a shape you give to a part of your pipeline.

The layers of a pipeline

A pipeline is made of stages, which are named phases such as “Build” and “Test.” Each stage holds steps. A wrapper step, like retry or timeout, holds other steps inside it. Wrappers can be placed inside each other, like nesting dolls. The order of the dolls changes the meaning.

flowchart TD
    P["Pipeline"] --> S["Stage Fetch Dependencies"]
    S --> R["Retry Wrapper with limit of 3 attempts"]
    R --> T["Timeout Wrapper for each attempt"]
    T --> B["Body Steps such as download command"]
    B -->|"Succeeds"| OK["Stage continues"]
    B -->|"Fails and attempts remain"| R
    B -->|"Fails on last attempt"| F["Failure reaches the stage"]
    F --> PF["Stage fails and build is marked failed"]
Fig 1. A retry wrapper around a timeout wrapper around the body steps, with failure escaping only after the last attempt

Reading the diagram

The stage contains a retry wrapper. Inside the retry sits a timeout, so every attempt gets its own time limit. Inside the timeout are the real steps. If the steps succeed, the stage continues. If they fail and attempts remain, control returns to the retry wrapper, which starts another attempt. Only when the final attempt fails does the failure travel outward to the stage, which fails, and the build is marked as failed.

Four places to use retry

PlaceWhat is retriedTypical use
Around one small stepOnly that stepA single download or upload
Around a group of stepsThe group, from its beginningFetch, unpack, and verify as a unit
As a stage optionThe whole stageA whole deployment check stage
As a pipeline optionThe entire pipelineRarely wise, because everything runs again
Everyday Analogy

Picture a cook making a sauce. If it splashes on the counter, they wipe up and stir again (retry one small step). If the whole pot burns, they must start the entire sauce over (retry a group). Sending the whole restaurant back to opening time (retry the pipeline) is almost never the right response.

Keep the wrapped area small

The smaller the retried block, the cheaper each retry is, and the fewer side effects can repeat. Wrap the one flaky action, not the whole stage that happens to contain it.

5How the Retry Step Works Internally

There is no magic here. The rules are few, and knowing them prevents most surprises.

Rule one: the count includes the first attempt

When you write a limit of three, the wrapped steps run at most three times in total. That is the original try plus up to two retries. Many beginners assume that three means “the first try plus three more,” which leads to confusion when they count attempts in the log.

Rule two: the body restarts from the top

Each attempt runs the entire wrapped block again from its first step. If the block has five steps and the fifth fails, all five run again. That is why small blocks are better than large ones: they repeat less work, and they repeat less that could be harmful to repeat.

Rule three: a failure is an exception

Inside Jenkins, a failing step raises an exception, a signal that says “something went wrong.” The retry wrapper catches it and decides whether to try again. A command that exits with a non-zero result also becomes such a failure, because the shell step turns it into one.

Rule four: a person aborting is not retried

If a human presses the abort button, retry does not fight it. The abort is respected, and the build stops. This is the correct behaviour, and it means retry cannot trap a build in a loop that people cannot escape.

Rule five: the final failure escapes

If the last allowed attempt fails, the failure propagates outward, exactly as if there had been no retry. The stage fails, and the build is marked failed. The log shows the earlier failures too, so you can see what happened.

Rule six: nothing is cleaned automatically

Retry does not clean the workspace, delete half-written files, stop leftover containers, or undo side effects. Whatever the failed attempt left behind is still there when the next attempt starts. Cleaning up is your job, and later chapters show how.

!
Why this matters

A retry that starts with a half-finished mess from the previous attempt can fail for a new reason, and the log then shows a confusing second error instead of the original one. Always think about what the first failure leaves behind.

Everyday Analogy

If a child knocks over a tower of blocks and you say “try again,” the blocks are still scattered on the floor. A sensible parent sweeps them together before the next attempt. Retry says “try again,” but it never sweeps the floor.

Rule

Count includes attempt one

A limit of three means three runs in total.

Rule

Whole block repeats

Every attempt starts at the block’s first step.

Rule

Aborts are respected

A person can always stop the build.

Rule

No automatic cleanup

Leftovers from failed attempts remain for the next one.

6Data Flow and Lifecycle of a Retried Step

Follow one flaky download through three attempts and see what the pipeline does at every moment.

sequenceDiagram
    participant PL as Pipeline
    participant RT as Retry Wrapper
    participant BD as Body Steps
    participant SV as Remote Server
    PL->>RT: Enter block with limit 3
    RT->>BD: Attempt 1
    BD->>SV: Request package
    SV-->>BD: Connection reset
    BD-->>RT: Failure raised
    RT->>RT: Attempts remain so run again
    RT->>BD: Attempt 2
    BD->>SV: Request package
    SV-->>BD: Server busy
    BD-->>RT: Failure raised
    RT->>BD: Attempt 3
    BD->>SV: Request package
    SV-->>BD: Package delivered
    BD-->>RT: Success
    RT-->>PL: Block completes and pipeline continues
Fig 2. A step that fails twice with transient errors and then succeeds on the third attempt

The lifecycle in plain steps

1

Enter

The pipeline reaches the retry block. The wrapper notes the limit and starts the first attempt.

2

Run

The body steps execute. They may talk to servers, files, or tools.

3

Fail or succeed

If everything passes, the wrapper finishes and the pipeline moves on. If a step raises an exception, the wrapper catches it.

4

Decide

The wrapper checks whether attempts remain, whether the failure was a human abort, and whether any retry conditions apply.

5

Repeat

If a retry is allowed, the body starts again from its first step, immediately, unless you added a wait.

6

Finish

Either an attempt succeeds, or the last attempt fails and the failure escapes to the stage.

What the log looks like

The build log shows each attempt as a separate stretch of output, with the failure message at the end of each. The wrapper also prints a short note that it is retrying and how many attempts remain. When you investigate a strange build, read all the attempts, because the first failure usually holds the real cause.

Time adds up

Three attempts of ten minutes each mean thirty minutes of waiting before the pipeline can fail. Always think about the worst case, not just the lucky case.

i
Tip

Print a short line at the start of the block, such as “Downloading dependencies, up to 3 attempts.” When someone reads the log at night, they immediately understand why the same lines appear more than once.

7The Ways to Write a Retry

Jenkins offers several places to put a retry. Each has a different reach.

The step form

The most common form is the retry step itself. You write its name, give it a number in brackets, and place the steps you want repeated inside braces after it. It works in both Declarative and Scripted pipelines, and it can be placed anywhere a step can go, including inside a stage, a parallel branch, or another wrapper.

The stage option

In Declarative Pipeline, a stage can carry an options section, and one of the available options is retry. Setting it tells Jenkins to run the entire stage again when the stage fails. This is convenient, but it repeats everything in the stage, including steps that were fine.

The pipeline option

The same option can be placed at the top of the pipeline, which retries the whole pipeline. This is rarely a good idea. A full pipeline can take an hour, and repeating it because of one blink in the last minute is wasteful.

The conditions form

Newer versions of the step accept a count together with a list of conditions, so it retries only for certain kinds of failure. Conditions are covered in their own chapter.

FormReachStrengthWeakness
Step around a small blockJust that blockPrecise and cheapYou must place it yourself
Step with conditionsJust that block, only for chosen failuresAvoids retrying real bugsNeeds a recent Jenkins version
Stage optionThe whole stageEasy to switch onRepeats successful work too
Pipeline optionThe whole pipelineOne lineSlow and costly, rarely advisable

A helpful rule

Use the smallest form that solves your problem. Prefer a step around one flaky action to a stage option, and prefer a stage option to a pipeline option.

Everyday Analogy

If a single bolt on a car is stuck, you try the bolt again. You do not disassemble the whole car and rebuild it from the factory floor. Choosing the size of the retry is choosing how much of the car you take apart.

!
Watch out

A retry option on a stage that contains deployment steps can deploy twice. Before you add a stage-wide retry, read every step in the stage and ask what happens if it runs again.

8What to Retry, and What to Leave Alone

This is the most valuable chapter in the guide. A retry on the wrong failure hides bugs and wastes money.

flowchart TD
    F["A step failed"] --> Q1{"Is the cause outside your code"}
    Q1 -->|"No, a bug or bad config"| N1["Do not retry. Fix the cause"]
    Q1 -->|"Yes"| Q2{"Is it likely to pass on a later try"}
    Q2 -->|"No, such as wrong password"| N2["Do not retry. Report clearly"]
    Q2 -->|"Yes, such as timeout or busy server"| Q3{"Is the action safe to repeat"}
    Q3 -->|"No, it changes real data"| N3["Make it idempotent first or do not retry"]
    Q3 -->|"Yes"| Y["Retry with a limit, a timeout and a wait"]
Fig 3. A decision path for deciding whether a failure deserves a retry

Good candidates

FailureWhy it is transient
Network timeout or connection resetNetworks blink and recover
Server busy or temporary error from a serviceLoad passes
Rate limit answerThe limit resets after a short time (wait before retrying)
Registry or package mirror hiccupMirrors restart or catch up
Build machine lost during a stepA new machine can be assigned
Short-lived lock on a shared resourceThe lock is released soon
Cloud resource still being createdIt becomes ready after a moment

Poor candidates

FailureWhy retry does not help
Compile or syntax errorThe code is wrong every time
Test assertion failureThe behaviour is wrong, not unlucky
Wrong or expired credentialsThe password stays wrong, and repeated attempts can lock the account
Missing file or wrong pathConfiguration mistakes do not heal
Permission deniedRules do not change between attempts
Invalid input rejected by a serviceThe same input is rejected again

The safe-to-repeat question

Even a transient failure needs one more check: can the action run twice without harm? Downloading a file twice is harmless. Charging a customer twice is not. If an action changes real data and is not idempotent, retry may do damage, and the action needs redesign first.

Everyday Analogy

If an elevator door fails to open, pressing the button again is fine. If an ATM freezes halfway through handing out cash, pressing “withdraw” again could take money twice. Some actions are safe to repeat, and some are not, and you must know which one you hold.

i
Tip

Keep a short list of the failures your team has genuinely seen and decided are transient, with the log text that identifies each. It turns retry from guesswork into policy.

9Retry Conditions: Retrying Only the Right Failures

Newer versions of the retry step can filter failures, so real bugs are not retried.

The problem with blanket retry

A plain retry treats every failure the same. A network blink and a compile error both trigger another attempt. The compile error will fail again, three times, and the team waits for no benefit.

The conditions idea

The step can be given a list of conditions together with its count. When conditions are given, the wrapper retries only if the failure matches one of them. Otherwise, the failure escapes immediately. Check the documentation for your Jenkins version, because the exact names and behaviour depend on the Pipeline plugin versions installed.

Conditions you may meet

Condition

Agent lost

Matches when the build machine disconnected or disappeared during the block. A new machine can pick up the work, so a retry is sensible.

Condition

Non-resumable

Matches when a step cannot resume after the Jenkins controller restarted. Retrying lets the block start fresh.

Condition

Kubernetes agent lost

Matches when a container-based agent was removed, for example by the cluster reclaiming resources. Provided by the Kubernetes plugin.

Idea

Custom conditions

When built-in conditions do not fit, teams write their own logic that inspects the failure and decides.

Infrastructure versus application failures

A helpful way to think: conditions such as agent loss describe infrastructure failures, where the work itself was fine but the place it ran vanished. Those are almost always worth retrying. Application failures, where the work itself went wrong, usually are not.

Benefits of conditions

  • Real bugs fail fast instead of after three attempts.
  • Infrastructure trouble still heals itself.
  • The policy is visible in the code.

Limits

  • Requires recent plugin versions.
  • Built-in conditions cover infrastructure, not network errors inside your commands.
  • Custom logic needs care and tests.
Everyday Analogy

A delivery company re-sends a parcel if the van broke down, because the parcel is fine. It does not re-send a parcel addressed to a house that does not exist. Conditions let you tell those two situations apart.

!
Watch out

Test how conditions behave on your own Jenkins before relying on them. A plain retry and a conditional retry treat ordinary command failures differently, and mixing them up can leave you with no retry at all when you expected one.

10Retry Together with Timeout

A retry without a timeout is a trap. A hung attempt never fails, so the retry never gets to act.

The hung attempt problem

Retry reacts to failures. But some problems do not fail. They hang. A download that connects and then sends nothing can wait for hours. To the retry wrapper, the attempt is still in progress, so nothing is retried, and an agent stays busy for no reason.

The timeout wrapper

The timeout step sets a maximum time for the steps inside it. When the time is up, Jenkins stops the block and raises a failure. Placed inside the retry, the timeout gives every attempt its own limit, so a hung attempt is cut off, and the retry can try again.

Inside or outside?

ArrangementMeaningWhen to use it
Timeout inside retryEach attempt has its own time limitGuarding against hung attempts
Timeout outside retryOne time limit for all attempts togetherCapping the total time a block may consume
BothA limit per attempt and a limit for the whole blockStrict budgets in critical pipelines

Choosing the numbers

Set the per-attempt timeout to a comfortable multiple of the normal duration. If a download normally takes thirty seconds, five minutes is generous and still catches a hang. Set the outer limit so that the whole worst case still fits your patience: three attempts of five minutes plus waiting is about seventeen minutes.

Check your version’s behaviour

How a timeout interacts with retry can differ between Jenkins and plugin versions, especially about whether a timeout counts as a retryable failure. Always test it once with a deliberately hanging command in a safe job, and write down what happens.

Everyday Analogy

A teacher who says “you may redo the test up to three times” but never ends a test period would find students staring at page one all afternoon. A time limit per attempt turns “try again” into something that can actually happen.

i
Tip

Whenever you write a retry around anything that touches the network, write a timeout right inside it in the same edit. Treat them as a pair.

11Waiting Between Attempts: Backoff and Jitter

Retrying instantly is often useless. If a server is overloaded, hitting it again a millisecond later just adds to the pile.

No built-in wait

The retry step starts the next attempt immediately. If you want a pause, you put a sleep step into the block, usually at the start of attempts after the first. Since the step does not tell the block which attempt it is on in most versions, people keep their own counter or write a small loop when they need growing waits.

Kinds of waiting

Fixed

Constant delay

Wait the same time before every retry, for example ten seconds. Simple and good enough for many cases.

Growing

Exponential backoff

Wait longer each time, such as 5, 10, 20, then 40 seconds. Gives a struggling service progressively more room to recover.

Random

Jitter

Add a small random amount to each wait. Without it, fifty builds that failed together retry together and fail together again.

Cap

Maximum delay

Limit the longest wait, so that backoff never grows into half an hour of idle time.

The retry storm

Imagine a package registry that hiccups for two seconds. Two hundred builds hit the error at once. All of them retry after exactly five seconds, and the registry, still recovering, receives two hundred requests in the same instant and fails again. This is a retry storm. Jitter spreads the retries out, and backoff thins them out over time.

Waiting for a condition instead

Sometimes you are not retrying a failure, but waiting for something to become ready, such as a newly created service. Jenkins has a waitUntil step that repeats a block until it returns true, with growing pauses between checks. It fits “wait for readiness” better than retry, which fits “repeat after failure.”

NeedBest tool
Repeat an action that sometimes failsRetry with a wait
Wait until a service is readywaitUntil with a timeout
Pause for a fixed timesleep
Different treatment by error typeRetry with conditions, or a small custom loop
Everyday Analogy

When a busy restaurant tells you there is a wait, you do not knock on the door every second. You come back in ten minutes. A hundred people all returning at exactly the same minute would create a new queue, so sensible guests come back at slightly different times. That is backoff with jitter.

12Retry Compared with Its Neighbours

Jenkins offers several ways to deal with failure. Picking the right one avoids a lot of confusion.

ToolWhat it doesBest for
retry stepRepeats a block of steps after failure, up to a limitTransient failures in a specific action
timeout stepStops a block that takes too longHung actions, budgets on time
waitUntil stepRepeats a check until it returns trueWaiting for readiness
sleep stepPauses for a fixed timeSimple delays, backoff pieces
try and catchHandles a failure with your own logicCustom recovery, cleanup, or alternate paths
catchErrorMarks the build or stage result but lets the pipeline continueNon-critical steps that must not stop everything
post sectionRuns actions after a stage or build, depending on the resultNotifications and cleanup
Tool’s own retry optionMany command-line tools can retry internallyDownloads and network calls, precisely tuned
Naginator pluginReruns a whole build after failureLegacy jobs, full-build flakiness
Restart from stageA person restarts a Declarative pipeline from a chosen stageManual recovery after a real fix

When the tool’s own retry is better

Many command-line tools can retry by themselves. A download tool such as curl can repeat a request several times with waits, and package managers have settings for retries and timeouts. These retry at the level of one network request, which is finer and cheaper than repeating a whole block in Jenkins. Use them first when they exist, and use the Jenkins retry step for the parts they do not cover.

Try and catch: retry’s clever cousin

When you need different behaviour by kind of error, such as retrying on a server error but stopping at a permission error, a small loop with try and catch gives you full control. It is more code, so keep it in a shared library step where every pipeline can reuse it.

Do not confuse retry with ignoring

The catchError step and its cousins do not retry. They accept a failure and continue. That is right for optional steps such as uploading a report, and wrong for steps the build cannot live without.

Everyday Analogy

A toolbox has a screwdriver, a hammer, and a wrench. They all fasten things, but they are not interchangeable. Retry is the tool for “try that again,” timeout is for “stop if it takes too long,” and catchError is for “shrug and carry on.” Using the wrong one makes the job harder.

i
Tip

Ask three questions in order. Can the tool retry by itself? Can a small, well-placed retry step do it? Only then reach for custom loops.

13Retrying Whole Builds: Naginator and Rebuilds

Sometimes the trouble is spread across a whole build, and teams want the entire job to run again.

The Naginator plugin

The Naginator plugin adds a post-build action to Jenkins jobs, often labelled “Retry build after failure.” When a build fails, it schedules a new run of the same job. You can set the maximum number of reruns, choose whether waiting time between reruns is fixed or growing, and decide which failures qualify, for example only those whose log matches a chosen text. It was created for classic freestyle jobs, and it can also be used with some pipeline jobs.

Why whole-build retry is a blunt tool

  • It repeats everything, including the stages that already passed.
  • It hides the flakiness inside a single, long build rather than pointing at the flaky step.
  • It multiplies cost: a one-hour build retried twice can consume three hours of agent time.
  • Side effects such as deployments and published packages can be repeated.

When it still makes sense

Whole-build retry is defensible for older jobs that cannot easily be restructured, for nightly builds where extra time is cheap, or as a temporary bandage while a team fixes the real source of the flakiness. Set a small limit, a delay, and a matching rule so that only known transient failures trigger it.

Manual alternatives

Manual

Rebuild

A person starts the same build again, often with the same parameters. Useful for one-off reruns.

Manual

Restart from stage

In Declarative pipelines, a person can restart from a chosen stage, reusing earlier results. Best after a genuine fix.

Auto

Naginator

Automatic rerun of the whole job, with limits and rules.

Auto

Step-level retry

Automatic rerun of just the risky block. Usually the best choice for pipelines.

Everyday Analogy

If one page of a printed report has a smudge, you reprint that page. Reprinting the whole two-hundred-page report because of one smudge wastes paper and time. Step-level retry reprints the page. Whole-build retry reprints the report.

!
Watch out

Never combine whole-build retry with step-level retry without doing the arithmetic. Three build reruns each containing three step attempts can mean nine attempts of the same flaky action, and a very long, very expensive failure.

14Idempotency and Side Effects

The biggest danger of retry is not the wasted time. It is doing something twice that should have been done once.

What is idempotency?

An action is idempotent if doing it twice has the same effect as doing it once. Pressing the “floor five” button in an elevator ten times still takes you to floor five. Adding one to a counter ten times does not. Retry is only really safe around actions that behave like the first kind.

Actions that are usually safe to repeat

  • Downloading a file or package.
  • Reading data, or running a read-only check.
  • Compiling code into a clean output folder.
  • Uploading a file to a fixed name, replacing what was there.
  • Setting a value to a specific state, such as “make sure this folder exists.”

Actions that are dangerous to repeat

  • Sending emails or messages to customers.
  • Charging money or creating orders.
  • Appending lines to a shared file or log.
  • Creating resources with generated names, so each attempt creates another one.
  • Running a database change that is not written to be run twice.
  • Incrementing version numbers, or tagging releases.

The half-done problem

A step can fail in the middle. The upload may have reached the server, but the confirmation was lost. From the pipeline’s point of view, the step failed. From the server’s point of view, the upload succeeded. A retry then uploads again. If the server rejects duplicates, the retry fails with a confusing “already exists” message. If it accepts duplicates, you now have two.

Making actions safe

1

Use fixed, predictable names

Name resources by build number or a stable key, so that a second attempt finds the first one instead of creating another.

2

Check before you act

Ask “does it already exist?” first, and skip the action when the answer is yes.

3

Use idempotency keys

Some services accept a unique key with each request and ignore repeats of the same key. Send the same key on each attempt.

4

Write repeatable changes

Design scripts and database changes so that running them twice leaves the same state.

5

Keep the retried block small

Wrap only the safe action, and leave the dangerous action outside.

Everyday Analogy

If you drop a letter into a post box and are not sure it went in, posting a second copy might cause the recipient to receive two. If you had written a reference number on the letter, the recipient could ignore the duplicate. An idempotency key is that reference number.

!
Never do this

Do not wrap a production deployment, a payment, or a customer message in a plain retry unless it has been designed to be repeated. A small wrapper can turn one problem into two.

15Cleaning Up Between Attempts

Retry does not sweep the floor. If the first attempt leaves a mess, the second attempt walks into it.

What a failed attempt can leave behind

Files

Half-written files

A partial download that looks like a real file. The next attempt may treat it as complete and fail in a strange way.

Processes

Running processes

A server or test process that was started and never stopped, still holding a network port.

Containers

Containers and networks

Containers with fixed names that block a new container of the same name.

Locks

Lock files

A lock left by the failed tool, preventing the next run of the same tool.

Data

Partial data

Rows or records written before the failure, in a test database.

Cloud

Cloud resources

Half-created resources that later attempts try to create again.

Cleaning strategies

  • Start each attempt clean. Put cleanup at the beginning of the retried block, so it runs before every attempt, including the first. Deleting a temporary folder and recreating it is a common pattern.
  • Use unique working folders per attempt, if the workspace makes cleanup awkward.
  • Use unique names for containers and resources, so a leftover cannot block a new one.
  • Clean in a failure handler, using try and finally logic or the post section, so that resources are released even when the block fails.
  • Prefer disposable environments. A fresh container per attempt is the cleanest cleanup of all.

Locks and retries

If your block holds a lock, such as one taken with the lockable resources feature, decide whether the lock should cover all attempts or each attempt separately. Holding the lock across all attempts keeps others out for longer. Releasing between attempts lets somebody else slip in and change the state you were preparing. Neither is universally right, but the choice should be deliberate.

LeftoverSymptom on the next attemptFix
Partial downloadCorrupt archive or checksum failureDelete the file before each attempt
Old process on a portAddress already in useStop processes in a cleanup step
Container with same nameName already in useUse unique names, remove containers on failure
Leftover lock fileAnother instance is runningRemove stale locks at the start
Half-created cloud resourceAlready exists errorCheck first, or use idempotent creation
Everyday Analogy

A painter who spills paint should clean the floor before the second try, not paint over the spill. Starting each attempt with a clean surface gives each attempt a fair chance.

16Flaky Tests: The Danger Zone

Wrapping a test stage in retry feels like an easy win. It is also the most misused application of the step.

What a flaky test is

A flaky test passes sometimes and fails sometimes on exactly the same code. Common causes include timing assumptions, shared test data, dependence on test order, outside services, and unpredictable resources like the clock or the network.

The temptation

Retrying the whole test stage makes red builds turn green, and the team’s pain goes away. But the flakiness is still there. It has just been hidden. Over time, the number of flaky tests grows, the retries grow, and build times grow with them. Worse, real bugs that fail intermittently get retried away, and they reach users.

The hidden cost

What retry gives

  • Fewer red builds in the short term.
  • Less clicking of rebuild.
  • Time to fix the flaky tests properly.

What it takes away

  • Visibility: flaky tests stop being noticed.
  • Time: every retry adds minutes to the build.
  • Honesty: a green build may hide a real intermittent bug.
  • Discipline: the problem becomes permanent.

A better approach

1

Retry only the failing tests, not the stage

Some test frameworks and build tools can rerun just the tests that failed. This is precise and cheaper than repeating the whole suite.

2

Record every retry that helped

If a test passes only on retry, log it and report it as flaky, instead of quietly showing green.

3

Track a flaky list with owners

Every flaky test gets an owner and a deadline. A test that stays flaky for too long is quarantined or deleted.

4

Limit the retries

One retry is usually the most a test should get. If two retries are needed, the test is broken.

5

Fix the causes

Remove timing assumptions, isolate data, and stub the outside world. Retry is a bandage, not medicine.

Everyday Analogy

A smoke alarm that beeps falsely gets its battery removed, and then the house is unprotected. Retrying flaky tests silences the false alarms, but it can also silence the real ones. The right fix is a better alarm, not a quieter one.

!
Watch out

If a team’s build success rate depends on retries, measure how often the second attempt saves the build. If it is more than a few percent, the retry is masking a quality problem that deserves real attention.

17Security Considerations

Retrying looks harmless, but repeated actions can create security problems of their own.

Repeated wrong logins

Many systems lock an account after several failed logins. If a pipeline uses a wrong or expired password and retry runs the login three times, the account may be locked, and every other pipeline that uses it fails too. Never retry authentication failures. A rejected password will not become correct by waiting.

Rate limits and blocks

Servers that see many requests from one address may block it. A retry storm from a build farm can look like an attack. Respect rate-limit answers, wait as the server asks, and add backoff and jitter so your requests spread out.

Secrets in repeated logs

Every attempt writes to the build log. If a step prints details about the request, such as headers or command lines, three attempts print them three times. Make sure retried blocks do not print secrets, and that masking is active in each attempt.

Side effects with real consequences

A retried deployment step or message to a customer is not only a reliability problem. It can be a security and compliance problem too, for example a change that is applied twice and breaks an audit trail. Keep retried blocks away from sensitive actions unless they are designed for repetition.

Retry as a way to hide attacks

Intermittent failures can also be clues. A service that fails occasionally for a suspicious reason, such as intermittent certificate errors, may indicate a misconfiguration or an interception attempt. If retries always cover them up, nobody notices. Log retried failures and review them from time to time.

Safer habits

  • Never retry login or permission failures.
  • Use backoff, jitter, and small limits.
  • Keep sensitive actions outside retried blocks.
  • Log every retried failure for later review.

Risky habits

  • Retrying authentication in a tight loop.
  • Ignoring rate-limit answers.
  • Printing secrets in retried steps.
  • Silencing all intermittent errors.
Everyday Analogy

A person who keeps entering a wrong PIN at a cash machine gets the card swallowed. Repeating a failed login is the same mistake at a larger scale. Some doors are locked for a reason, and knocking harder does not help.

18Performance, Cost, and Scalability

Every retry uses agent time, network capacity, and patience. At scale, small habits become big bills.

The cost of an attempt

If a block usually takes two minutes and fails three times before a lucky fourth attempt, it costs eight minutes of agent time, plus waiting. Multiply by hundreds of builds and dozens of stages, and retry can consume a noticeable share of your build capacity.

The retry budget

A retry budget is a limit on how much retrying is acceptable, for example “no more than five percent of attempts may be retries.” If retries exceed the budget, something is wrong in the underlying system, and the team must investigate rather than add more retries.

Practical guidance

Limit

Small counts

Two or three attempts are enough for most transient problems. If ten are needed, the service is broken.

Time

Timeouts on every attempt

Cap the cost of one attempt and of the total.

Wait

Backoff with jitter

Prevents build farms from hammering a recovering service together.

Scope

Small blocks

Repeating a two-second download is cheap. Repeating a forty-minute test stage is not.

Cache

Use local mirrors and caches

Fewer outside calls means fewer chances to fail. A nearby package mirror removes many network failures altogether.

Fail

Fail fast on permanent errors

Use conditions so bugs do not consume retries.

Retries at scale

When the same outage hits hundreds of builds at once, retries multiply the load on the affected service. Build farms need a shared policy for backoff and jitter. A shared library step that every pipeline uses is the most practical way to enforce one policy across everything.

Root causes are cheaper than retries

Often the best performance improvement is to remove the cause of the transient failure: use a closer mirror, raise a connection limit, fix a slow database, or cache dependencies. Retry is the cheapest fix to write, and often the most expensive to keep.

2 to 3
Attempts are enough for most transient failures
Budget
Track how much of your build time is retries
Fix cause
A local mirror beats a retry loop
Everyday Analogy

Reheating a meal several times uses electricity every time. A well-run kitchen tries to serve it hot the first time. Retries are like reheating: sometimes necessary, but a habit that costs more than it seems.

19High Availability and Reliability

Retry helps a pipeline survive small hiccups. It cannot replace a reliable system underneath.

What retry can survive

  • Short network problems: a dropped connection heals within seconds.
  • Busy services: a server that briefly refuses work recovers.
  • Lost build machines: another machine can take over the block.
  • Controller restarts: some steps cannot resume afterwards, and a retry can run them again.

What retry cannot survive

  • Long outages: if a service is down for an hour, three attempts over two minutes all fail.
  • Permanent faults: wrong configuration, missing permissions, or code bugs.
  • Corrupted state: a retry cannot repair a broken database or a damaged cache.

Agent loss and resumability

Pipelines are built to pause and resume, so many steps survive a restart of the Jenkins controller. But a running shell command on a machine that vanished cannot continue. That failure is an infrastructure failure, and the conditions of the retry step exist for exactly this. With cloud and container agents that come and go, agent loss becomes a normal event that a good pipeline expects.

Combine retry with other defences

1

Timeouts

Stop hung actions so retry can act.

2

Mirrors and caches

Reduce dependence on far-away services.

3

Alternative sources

If a primary registry fails repeatedly, try a backup one, which is a simple form of failover.

4

Circuit breaking

Stop retrying a service that has failed many times in a row, and report the outage instead.

5

Clear failure messages

When retries end, say exactly what failed and what people should check.

Fail loudly after the last attempt

A pipeline that swallows the final failure is worse than one that fails. Make sure that when all attempts are used, the build reports clearly, notifies the right people, and includes the reason from the last error.

i
Tip

Retries help the average build, but on-call engineers care about the bad day. Plan for the outage that lasts an hour, not only the blink that lasts a second.

Everyday Analogy

A car’s spare tire helps with one flat. It does not help if the road is closed. Retry is the spare tire of a pipeline: excellent for the common puncture, useless when the whole bridge is out.

20Monitoring, Logging, and Metrics

A retry that nobody can see is a problem waiting to grow. Make retries visible.

Why visibility matters

Because retry turns failures into successes, a healthy-looking green dashboard can hide an unhealthy system. If half your builds need a second attempt, you are running on luck. Only measurement reveals it.

What to log

  • The start of each retried block, with the limit.
  • Each failure’s short reason, in plain words.
  • The wait before the next attempt.
  • The final result: succeeded on attempt two, or failed after three.

What to measure

Retry rate
Share of blocks that needed more than one attempt
Save rate
Share of retried blocks that eventually succeeded
Wasted time
Agent minutes spent on failed attempts

Reading the numbers

PatternWhat it probably meansAction
Rising retry rate for one stepA dependency is degradingInvestigate that service, add a mirror or cache
Retries almost never save the buildFailures are permanent, retry wastes timeRemove the retry or add conditions
Retries always save on attempt twoA steady, small flakinessFix the root cause while the retry holds
Spikes at particular hoursShared resource contention or maintenance windowsReschedule work, add capacity
Different failure textsSeveral causes hidden under one retrySplit the block or add conditions

Getting the data

Teams collect these measurements in several ways: by having a shared library step write a standard line to the log that a log system can count, by sending a small counter to a metrics system, or by reading build logs afterwards. A shared step that all pipelines use makes the data consistent.

Alerts

Alert the owning team when a step’s retry rate crosses an agreed threshold, when a retried block starts failing after all attempts, or when total retry time grows unusually. Do not alert on every single retry, because retries are working as designed.

i
Tip

Put a “builds saved by retry” number on a shared dashboard. Teams start asking why the number is so high, and that question leads to real fixes.

Everyday Analogy

A car that needs two turns of the key every morning still gets you to work, but a good driver notices and visits the garage before winter. Retry counts are the number of times you turned the key.

21Testing Your Retry Logic

Retry code is rarely tested, because it seems simple. That is exactly why it hides bugs.

Why test it?

Retry runs only when things go wrong, so mistakes in it appear only on bad days. A wrong count, a missing wait, or a cleanup that fails can turn a small glitch into a long outage. Test retry on purpose, on a quiet day.

Ways to test

Test

A step that fails first

Write a small test job with a step that fails the first one or two times and then succeeds, using a counter file in the workspace. Confirm that the block succeeds on the right attempt.

Test

A step that always fails

Confirm that the failure escapes after the last attempt, with a clear message, and that the total time matches your budget.

Test

A step that hangs

Confirm that the timeout cuts the attempt and that the retry then behaves as you expect in your Jenkins version.

Test

Cleanup check

Leave debris on purpose in a failing attempt and confirm that the next attempt starts clean.

Test

Permanent error

Confirm that a login failure or a compile error is not retried when conditions or filters say so.

Test

Abort test

Press abort during a retry and confirm the build stops instead of starting another attempt.

Test shared library steps

If retry logic lives in a shared library step, it deserves unit tests with a pipeline testing framework, where you can simulate failures and check how many times the body ran and how long the waits were. Since this one step protects hundreds of pipelines, it deserves the best tests in your library.

Rehearse the outage

Once a quarter, deliberately break a dependency in a test environment, for example by blocking access to a mirror, and watch what happens to your pipelines. Do they retry sensibly? Do they fail with a clear message? Do the alerts fire?

Everyday Analogy

A fire drill tests the exit doors on a calm day, so that people know what to do on a bad one. Failure drills for your pipelines serve the same purpose for your retry logic.

22Standard Retry Policy with Shared Libraries

When every team writes its own retry, you get dozens of styles. A shared library gives you one good one.

The problem with scattered retries

Without a common approach, one pipeline retries five times with no wait, another retries twice with a fixed wait, and a third has no retry at all. Some print helpful messages, and some print nothing. When an outage happens, some pipelines hammer the failing service, and others give up too early.

flowchart LR
    T1["Team A Jenkinsfile"] --> LIB["Shared Library Retry Step"]
    T2["Team B Jenkinsfile"] --> LIB
    T3["Team C Jenkinsfile"] --> LIB
    LIB --> POL["Standard Policy with limits, timeout, backoff and jitter"]
    POL --> CLS["Failure Classifier for transient or permanent"]
    CLS --> ACT["Retry with wait or fail fast"]
    LIB --> LOG["Standard Log Lines and Metrics"]
    LOG --> DASH["Dashboard and Alerts"]
Fig 4. Many pipelines share one retry step that applies a common policy and reports common metrics

What a standard retry step can do

  • Apply a sensible default number of attempts and a per-attempt timeout.
  • Add exponential backoff with jitter and a maximum delay.
  • Classify failures as transient or permanent using known patterns, and fail fast on permanent ones.
  • Print clear, uniform log lines for each attempt.
  • Send a count to a metrics system.
  • Refuse to wrap steps that are marked as unsafe to repeat.

Design guidelines

ChoiceGuideline
Default attemptsThree, including the first
Default waitShort and growing, with jitter and a cap
TimeoutRequired, with a sensible default
OverridesAllowed within limits, so nobody can set a hundred attempts
LoggingAlways on, never printing secrets
NameSays what it does, such as a name that includes “withRetry”

Cloud and configuration as code

Agents in the cloud come and go, and network calls cross many boundaries. Keep the retry defaults in the library and the library version in your configuration files, so a policy change reaches everyone through a reviewed release. Cloud teams often pair the pipeline policy with the retry settings built into their cloud tools, so that both layers cooperate rather than multiply.

!
Watch out

Layered retries multiply. If your pipeline retries three times and the tool inside retries three times, one failing request is attempted nine times. Decide which layer owns the retry, and turn the other off.

Everyday Analogy

A company that gives every branch its own way of handling a returned parcel gets confusion. One written procedure, followed by everyone, gives customers the same experience and gives managers one place to improve it. A shared retry step is that procedure.

23Advantages, Disadvantages, and Trade-offs

Retry is one of the cheapest ways to make pipelines calmer, and one of the easiest to misuse.

Advantages

  • Short glitches heal without human help.
  • Very small change to the pipeline.
  • Reduces build noise and rebuild clicking.
  • Works with any steps, in any pipeline style.
  • Can be narrowed with conditions.
  • Easy to standardise in a shared library.

Disadvantages

  • Can hide flaky tests and real intermittent bugs.
  • Repeats side effects if actions are not idempotent.
  • Adds time and cost on failure.
  • No built-in wait, so storms are easy to cause.
  • Does not clean up leftovers.
  • Layers of retry multiply attempts.

Resilience versus honesty

ChoiceLeans toward resilienceLeans toward honesty
Number of attemptsSeveralOne or two
ScopeWhole stageSingle action
Which failuresAll of themOnly known transient ones
ReportingShow green after a saveMark the build as unstable when a retry was needed

Showing that a retry happened

One useful compromise is to let the build succeed after a retry, but record that a retry was needed, for example in the build description or as a marker in the results. Then the pipeline stays green, and the team still sees the cost.

There is no universal answer. A team with a very stable internal network needs little retry. A team that downloads from the public internet through many hops needs more. Match the design to your environment, your risks, and your patience.

24Design Patterns and Anti-patterns

A pattern is a solution many teams discovered independently. An anti-pattern is a trap many teams fell into.

Patterns worth copying

Pattern

Small block, per-attempt timeout

Wrap one flaky action, with a timeout inside the retry, and a small attempt limit.

Pattern

Backoff with jitter

Wait a growing, slightly random time between attempts, up to a cap.

Pattern

Clean start

Begin each attempt by clearing leftovers, so each one starts fresh.

Pattern

Fail fast on permanent errors

Use conditions or classification so bugs and bad credentials stop immediately.

Pattern

Backup source

After repeated failure on a primary mirror, try a secondary one.

Pattern

Mark saved builds

Record that a retry was needed, so hidden flakiness stays visible.

Anti-patterns to avoid

ANTI-PATTERN 01Avoid
The Blanket Retry

Putting retry around the entire pipeline or around every stage “just in case.” Bugs are repeated, time is wasted, and real problems are hidden.

Better approach

Retry only specific, known-flaky actions, with conditions or classification.

ANTI-PATTERN 02Avoid
The Instant Hammer

Retrying immediately, many times, with no wait. It adds load to a service that is already struggling.

Better approach

Add a wait, growing with each attempt, with jitter and a cap.

ANTI-PATTERN 03Avoid
Retry Wrapped Around Deploy

Wrapping a deployment or payment in retry when it is not safe to repeat. Two deployments or two charges result.

Better approach

Make the action idempotent first, or keep it outside the retry block.

ANTI-PATTERN 04Avoid
The Retry Tower

Retries inside retries inside retries: the pipeline, the stage, the step, and the tool each retry three times. One failure turns into eighty-one attempts.

Better approach

Choose one layer to own the retry and disable the others.

ANTI-PATTERN 05Avoid
The Silent Save

Retrying without logging or metrics, so nobody knows how often builds are being rescued.

Better approach

Log every attempt and count retries. Review the numbers regularly.

25Best Practices and Common Mistakes

These are lessons that teams usually learn the hard way. You can learn them the easy way.

Best practices

  • Retry only transient failures. Fail fast on bugs, bad configuration, and login errors.
  • Keep the retried block small, wrapping one action rather than a whole stage.
  • Use a timeout inside every retry that touches a network or a slow tool.
  • Add a wait, ideally growing, with jitter and a cap.
  • Keep attempts low, normally two or three.
  • Make retried actions idempotent and start each attempt from a clean state.
  • Prefer the tool’s own retry for single requests, and own only one retry layer.
  • Log each attempt and never print secrets.
  • Measure retry rate and save rate, and set a budget.
  • Standardise in a shared library so all teams follow one policy.
  • Fix root causes, using retry as a bridge, not a home.

Common mistakes and their fixes

MistakeWhat happensFix
Assuming the limit means extra retriesOne attempt fewer than expectedRemember that the count includes the first attempt
No timeout inside the retryA hung attempt blocks everythingAdd a per-attempt timeout
Retrying login failuresAccounts get lockedDo not retry authentication and permission errors
Retrying the whole test stageFlaky tests hide, builds slow downRerun only failing tests and track flakiness
No cleanup between attemptsSecond attempt fails for a different reasonClean at the start of the block
Layered retriesAttempts multiplyChoose one owning layer
Retry around a non-idempotent actionDuplicate deployments, messages, or chargesRedesign, or keep it outside the block
Not reading the first failureDebugging the second, misleading errorRead all attempts, starting with the first
!
A classic trap

The build is green, so nobody looks. But the log shows three attempts on every download. The pipeline is healthy in appearance only. Review retried steps regularly, even when the builds are green.

26A Worked Example: Hardening a Flaky Pipeline

Let us walk through a full improvement for a fictional team, step by step, without writing any code.

The situation

Harbourline Software has a web service pipeline with five stages: fetch dependencies, compile, unit tests, build a container image, and publish the image to a registry. About one build in six fails for no clear reason. Developers press rebuild without reading the log, and the on-call engineer has stopped trusting red builds.

Step by step

1

Collect evidence

The team reads the logs of thirty failed builds and sorts the failures: twelve were dependency downloads, six were the registry publish, five were lost build machines, and seven were real test failures.

2

Decide what is transient

Downloads, publishing, and lost machines are transient. Real test failures are not. The team resolves not to retry tests.

3

Fix causes first where cheap

They set up a local package mirror, which removes most download failures without any retry.

4

Wrap the download

The remaining download step gets a small retry of three attempts, with a per-attempt timeout of five minutes and a short growing wait with jitter.

5

Make publishing safe to repeat

The publish step is changed to use the build number as a fixed tag. Before publishing, it checks whether the tag already exists. Only then is the publish step wrapped in a retry of two attempts.

6

Handle lost machines with conditions

For the compile and build stages, the team uses a retry with agent-loss conditions, so infrastructure failures are retried and code errors are not.

7

Add cleanup

Each retried block begins by removing partial downloads and temporary containers with fixed names.

8

Log and measure

A shared library step prints each attempt and records a count. The build description notes when a retry was needed.

9

Review after a month

The team compares retry rate, save rate, and build duration, and decides what else to fix.

The result after one month

MeasureBeforeAfter
Builds failing for unclear reasonsAbout one in sixAbout one in fifty
Manual rebuilds per weekDozensA handful
Real test failures noticed quicklyOften ignoredTaken seriously again
Retries that saved a buildNot measuredTracked, and falling as causes are fixed
i
Lesson

The team did not start by adding retry everywhere. It started by reading the failures, fixed the cheapest causes, and used retry only where the evidence showed transient trouble. Evidence first, retry second.

27Migrating from Blanket Retries to a Retry Policy

Many teams already have retries scattered around. Here is how to bring order without breaking builds.

What you may find

  • A retry around the whole pipeline, added years ago by someone who has left.
  • A stage option that retries a slow test stage five times.
  • A hand-written loop with an unknown number of attempts and no wait.
  • A whole-build retry plugin setting on old jobs.
  • Tool-level retries inside scripts, combining with pipeline retries.

A safe migration path

1

Inventory

Search all Jenkinsfiles, shared libraries, and job settings for retries, loops, and rerun plugins. Write down where each one is and what it wraps.

2

Measure before touching

For a few weeks, record how often each retry actually saves a build. Retries that never save anything are candidates for removal.

3

Remove the dangerous ones first

Take retries away from deployment, publishing, and payment steps, unless they are made idempotent.

4

Narrow the broad ones

Replace stage-wide and pipeline-wide retries with retries around the specific flaky actions.

5

Introduce the standard step

Publish the shared library retry step, and convert pipelines to use it a few at a time.

6

Fix root causes

Where measurements show a steady flaky action, invest in a real fix such as a mirror, a cache, or a corrected test.

7

Retire whole-build retry

Once step-level retry is in place, turn off rerun plugin settings so attempts do not multiply.

!
Watch out

Removing a long-standing retry can make builds seem to get worse overnight, because the hidden flakiness suddenly shows. Warn the team, and treat the newly visible failures as valuable information, not as a regression.

The reward

After migration, every retry in your pipelines is deliberate, small, measured, and safe. Failures that remain are meaningful, and the team trusts red builds again.

28Team Agreements: Living with Retries

A retry policy works best when the team agrees on it and reviews it together.

Agree on the defaults

Write down the standard number of attempts, the standard wait, the standard timeout, and where these are set. Put them in the contributing guide, so that every new pipeline follows the same rules.

Agree on what may be retried

  • A list of actions that are approved for retry: downloads, uploads to fixed names, readiness checks.
  • A list of actions that must never be retried without redesign: payments, customer messages, uncontrolled deployments.
  • A rule that authentication and permission failures are never retried.

Agree on visibility

Every retry writes a standard log line and counts toward a shared metric. A weekly or monthly review looks at the top retried steps and asks what could remove the need.

Agree on ownership

The owner of the shared retry step decides defaults, reviews requests for exceptions, and publishes changes. Each team owns the retries in its own pipelines and answers for their numbers.

Rule

Retry needs a reason

Every retry in a pull request comes with a short note about which failure it targets.

Rule

Retry has an owner

Someone is responsible for revisiting it and removing it when the cause is fixed.

Rule

Retry is measured

Numbers, not feelings, decide whether a retry stays.

Rule

Retry is temporary where possible

A retry that hides a fixable problem should carry a target date for removal.

Everyday Analogy

A hospital has a written rule for when a test may be repeated and when a doctor must be called. Without the rule, one nurse repeats everything and another repeats nothing. A team retry policy is the same kind of shared rule.

29Real-World and Industry Examples

These scenarios show how organisations use retry. They are illustrative, so you can map them to your own situation.

Scenario: the public package registry that blinks

A team downloads hundreds of libraries from a public registry for every build. Once or twice a day the registry answers with a temporary error for a few seconds. A small retry with a short wait around the dependency step turns those blips into invisible events. Later the team adds a local mirror, and the retry rarely fires.

Scenario: cloud agents that disappear

A company runs Jenkins agents as short-lived containers on a shared cluster. Occasionally the cluster reclaims a container in the middle of a build. A retry with an agent-loss condition restarts the block on a fresh container. Builds succeed, and the team sees the occasional retry in a dashboard without any human action.

Scenario: the readiness check after deployment

After deploying a service to a test environment, a pipeline must wait until it is ready. Instead of retrying a failing check, the team uses a wait-until step with growing pauses and a firm time limit. If the service is not ready after ten minutes, the pipeline fails with a clear message.

Scenario: the rate-limited service

Many builds call a public service that limits requests. When the limit is hit, it says so and asks clients to wait. The shared retry step respects that answer, waits a random amount around the requested time, and tries again, so the build farm does not hammer the service as a crowd.

Scenario: the retry that hid a real bug

A team wrapped its test stage in retry three years ago. Slowly the stage grew from ten to thirty minutes. Investigation showed that a genuine race condition in the product caused one test to fail about a third of the time, and the retry had been hiding it. Removing the retry made the bug visible, and fixing it improved both the product and the build time.

What these examples share

In every good case, retry targets a known transient cause, sits around a small, safe block, has a timeout and a wait, and is measured. In the bad case, retry was broad, silent, and unmeasured, and it hid the very information the team needed.

Retry buys time to fix the cause. It should never replace the fix.

30How Other CI Tools Handle Retries

Every modern automation system offers some way to deal with transient failure. Comparing them shows what is essential.

ToolIts approach to retryNotable difference
JenkinsThe retry step, stage and pipeline options, plus plugins for whole-build rerunsFlexible and code-based; you build the wait and classification yourself
GitLab CI/CDA retry setting on jobs, with a maximum and optional conditions such as runner failuresConfigured per job, with built-in failure categories
Azure PipelinesA retry count on tasksSimple per-task count
BuildkiteAutomatic retry rules by exit statusRules keyed by exit codes
GitHub ActionsNo general built-in step retry as far as I know; teams use community actions, shell loops, or rerun failed jobs manuallyManual rerun of failed jobs is a first-class feature
CircleCIReruns of failed jobs or tests, with test-level rerun optionsFocus on rerunning failed tests

Feature sets change quickly, so check each tool’s current documentation before you rely on this table.

What Jenkins does differently

Jenkins gives you a small, general building block and expects you to compose a policy from it: timeouts, waits, conditions, and shared library steps. Some other tools bake failure categories into job settings. Jenkins gives more freedom and more responsibility, which is why a shared standard step is so valuable.

What is universal

The lessons apply everywhere: retry transient failures only, keep blocks small and safe to repeat, wait with backoff and jitter, cap attempts and time, own one retry layer, and measure how often retries save the build.

31Advanced Topics: Circuit Breakers, Budgets, and Classification

Once the basics feel comfortable, these ideas help larger teams and busier build farms.

Circuit breakers

A circuit breaker is a rule that stops trying a service that keeps failing. In an electrical panel, a breaker trips when there is too much current, protecting the wiring. In a pipeline, a breaker might say, “if the registry failed the last ten builds in a row, stop retrying and fail immediately with a clear outage message.” This saves time and reduces the load on the struggling service.

Failure classification

A custom retry step can look at the failure and decide what kind it is: a network error, a rate limit, a timeout, an authentication error, or a build failure. Each class gets its own treatment. Network errors get a retry with backoff. Rate limits get a longer, server-guided wait. Authentication errors and build failures fail at once. Keep the list of patterns small, tested, and documented.

Exit codes

Command-line tools report their result as a number called an exit code. Zero means success. Other numbers mean various kinds of failure, and some tools use specific codes for temporary problems. A custom step can capture the exit code and retry only for codes known to be transient.

Retry budgets across the pipeline

Instead of allowing three attempts per step, a pipeline might have a total budget, such as “at most five retries across the entire run.” When the budget is used up, the next failure fails immediately. This stops a sick run from consuming an hour of retries across many stages.

Idempotency keys

For actions that call outside services, send a unique key with each logical request, the same on every attempt. The service can recognise duplicates and process the request only once. Where a service supports keys, this makes retry safe even for actions like creating orders or launching cloud resources.

Hedging and other tricks

Some large systems send a second request if the first is slow, without waiting for failure, and use whichever answers first. This trades extra load for lower delay. It is rarely appropriate for build pipelines, but it shows the wider family of techniques that retry belongs to.

Next

Circuit breaker

Stop trying a service that keeps failing.

Next

Classifier

Choose the treatment by kind of failure.

Next

Run-wide budget

Cap total retries across the pipeline.

Next

Idempotency keys

Let outside services ignore duplicate requests.

i
Tip

Add advanced features one at a time, and only after the simple version is measured and stable. A clever retry policy that nobody understands is another source of surprise.

32Troubleshooting Retry Behaviour

When something feels wrong, walk through these questions in order.

1

How many attempts really ran?

Count the attempts in the log. Remember that the limit includes the first attempt, so a limit of three shows three runs, not four.

2

What did the first attempt fail with?

Read the first failure, not the last. Later failures are often side effects of a messy first one.

3

Why was no retry performed?

Check for a human abort, for retry conditions that did not match, and for a failure raised outside the retried block.

4

Why did it retry so many times?

Look for layered retries: a pipeline option, a stage option, a step, a plugin, and a tool option may all be active together.

5

Did the attempt hang?

A hung attempt never fails, so retry never acts. Check for a timeout inside the retry, and how your version treats a timeout.

6

What did the previous attempt leave behind?

Look for partial files, running processes, existing containers, and stale locks.

7

Did a side effect repeat?

Check the target system for duplicates: two deployments, two messages, two resources. If found, remove the retry or make the action idempotent.

SymptomLikely causeFirst check
Build takes far longer than usualRepeated attempts, each with long timeoutsCount attempts and durations in the log
Second attempt fails with a different errorLeftovers from the first attemptCleanup at the block start
No retry happens at allCondition did not match, or human abortConditions and how the failure was raised
Duplicate resources or messagesNon-idempotent action inside retryWhat the block does on repeat
Account locked outLogin failure was retriedRemove retry from authentication
Service overwhelmed after an outageRetry storm without jitterAdd backoff and jitter in a shared step
i
Tip

Keep a short page for developers explaining how retries are set up in your pipelines, what the standard defaults are, and how to read a log with several attempts. It prevents many panicked messages.

33Glossary of Terms

Every important word from this guide in one place, explained in plain language.

TermPlain meaning
AgentA worker machine or container that runs pipeline steps for Jenkins.
AttemptOne run of the steps inside a retry block. The first run counts as attempt one.
BackoffWaiting between attempts, usually longer each time.
Build noiseFailures that have nothing to do with code quality, which erode trust in builds.
Circuit breakerA rule that stops trying a service that keeps failing.
ConditionA test that decides whether a failure deserves a retry.
ControllerThe central Jenkins server that runs pipelines and schedules work.
ExceptionThe signal a failing step raises to say that something went wrong.
Exit codeThe number a command returns to report its result, with zero meaning success.
Flaky testA test that sometimes passes and sometimes fails on the same code.
IdempotentSafe to repeat, because a second run leaves the same result as the first.
Idempotency keyA unique key sent with a request so that a service can ignore repeats.
JenkinsfileThe text file that defines a pipeline, stored beside the source code.
JitterA small random change to waiting time so clients do not retry in unison.
NaginatorA plugin that reruns a whole build after failure.
Permanent failureA problem that stays until someone fixes it.
Rate limitA server’s cap on how many requests a client may make in a period.
Retry budgetA limit on how much retrying is acceptable overall.
Retry stormMany clients retrying together and overwhelming a recovering service.
StageA named phase of a pipeline, such as Build or Test.
StepOne action inside a pipeline.
TimeoutA maximum time allowed for a block of steps.
Transient failureA problem that goes away by itself, such as a brief network error.
waitUntilA Jenkins step that repeats a check until it returns true.

34Frequently Asked Questions

Short answers to the questions people ask most.

Q1What does the retry step do in one sentence?
It runs a block of pipeline steps again when they fail, up to a limit you choose, and lets the failure escape only after the last attempt fails.
Q2Does a limit of three mean three retries?
No. The count includes the first attempt, so a limit of three means one original run plus at most two retries.
Q3Does retry wait between attempts?
No. The next attempt starts immediately. Add a sleep step, or a small loop with growing waits, when you want a pause.
Q4Should I wrap my whole pipeline in retry?
Almost never. It repeats successful work, wastes time, repeats side effects, and hides real problems. Wrap the smallest block that contains the flaky action.
Q5Will retry stop when I press abort?
Yes. A human abort is respected and does not trigger another attempt.
Q6Can I retry only certain kinds of failure?
In recent versions, the step accepts conditions such as agent loss, so only matching failures are retried. For other rules, use a small custom loop, ideally in a shared library step.
Q7Is it a good idea to retry failing tests?
Be careful. Retrying a whole test stage hides flaky tests and real intermittent bugs. Prefer rerunning only the failing tests, tracking every retry that helped, and fixing the causes.
Q8What is safe to retry?
Actions that are safe to repeat, such as downloads, read-only checks, and uploads to fixed names. Avoid retrying payments, customer messages, and uncontrolled deployments unless they were designed for repetition.
Q9Why do I need a timeout inside the retry?
Because a hung attempt never fails, so retry never acts. A per-attempt timeout turns a hang into a failure that retry can handle.
Q10What is the difference between retry and waitUntil?
Retry repeats a block after it fails. WaitUntil repeats a check until it returns true, which suits waiting for something to become ready.
Q11Why did my build make so many attempts?
Retries may be layered: a pipeline option, a stage option, a step, a plugin, and a tool’s own setting can all be active at once. Their counts multiply, so choose one owning layer.
Q12How do I know if my retries are healthy?
Measure the retry rate and how often a retry saves the build. If retries are frequent, or rarely save anything, investigate the cause instead of adding more attempts.

35Summary and Key Takeaways

The retry step gives a pipeline a second chance. Used with judgement, it makes builds calmer. Used carelessly, it hides the very problems you need to see.

You began with a coffee machine that needed a second press and finished with a full policy for retrying pipeline steps. Along the way you learned how the count works, how the block restarts, how to add timeouts and waiting, how to tell transient failures from permanent ones, why idempotency and cleanup matter, and how to measure and standardise retries across a team. The main rules are simple: retry only transient failures, keep the block small, add a timeout and a wait, make the action safe to repeat, and measure what you rescue.

Key Takeaways

  • Retry repeats a block after failure. The count includes the first attempt, the whole block restarts, and only the final failure escapes.
  • Retry transient failures only. Network blips, busy servers, and lost agents deserve another try. Bugs, bad configuration, and wrong passwords do not.
  • Always pair retry with a timeout, and add a wait. A hung attempt never fails, and instant retries can start a storm. Use backoff with jitter and a cap.
  • Make retried actions safe to repeat. Use idempotent actions, fixed names, existence checks, and idempotency keys, and clean up leftovers at the start of each attempt.
  • Keep the scope small and the layers few. Wrap one action, not a stage or a pipeline, and let only one layer own the retry so counts do not multiply.
  • Do not use retry to hide flaky tests. Rerun only failing tests, record every save, and fix the causes.
  • Standardise and measure. Use a shared library step with one policy, log each attempt, track retry and save rates, and set a budget.