What Are Environment Variables in Jenkins?

What Are Environment Variables in Jenkins?

The named values that every build can read. Learn what they are, which ones Jenkins gives you for free, how to create your own at different levels, how to handle secrets safely, how scope and precedence work, and how to avoid the classic mistakes.

Picture a busy workshop with a whiteboard on the wall. On the board are a few short notes: “Today’s date”, “Customer name”, “Box size: large”, “Delivery address”. Every worker glances at the board when they need a fact, so nobody has to ask the manager the same question a hundred times. If the address changes, the manager updates one line on the board, and everyone automatically uses the new one.

Environment variables are that whiteboard. They are named values, such as a build number or a target server, that are placed around a running program so that it can read them when needed. Jenkins fills the board with many useful notes for every build, and lets you add your own. Steps in your job can read those notes instead of having facts typed into them again and again.

In this guide you will learn what environment variables are, which ones Jenkins provides, how to create your own in Freestyle projects and in Pipelines, how scope decides which step can see which value, how to handle secrets without leaking them, how variables differ from parameters and credentials, and how to solve the puzzles that trip up almost every beginner. Every new word is explained the first time it appears.

1What Is an Environment Variable?

An environment variable is a named piece of text that a running program can look up by its name.

Let us build the idea from the ground up. A variable is a name attached to a value, like a label stuck on a jar. The label says “sugar”, and the jar holds the sugar. You can change what is inside the jar without changing the label. An environment is the set of surroundings a program runs in. So an environment variable is a labelled value that lives in the surroundings of a program, where the program can read it whenever it wants.

Every computer already has them. The variable PATH tells your terminal where to look for programs. The variable HOME names your personal folder. Programs read these quietly without asking you. Jenkins uses the same well-known mechanism: before it runs a step, it places a set of variables in the surroundings of that step. Your commands, scripts and tools can then read them by name.

Two facts are worth remembering right away. First, every environment variable is text. Even a number such as a build number is stored as a piece of text, and the program that reads it must convert it if it needs arithmetic. Second, environment variables are looked up at the moment of use, so changing one changes the behaviour of every step that reads it, without editing those steps.

Name
Each variable has a label such as BUILD_NUMBER
Text
Every value is stored as text
Scoped
Visibility depends on where it is defined
Analogy

Think of environment variables as the labelled sticky notes on a shared whiteboard. Any worker can read a note by its label. The manager can replace a note in one second, and everyone immediately uses the new value, without anyone rewriting their instructions.

2Why Environment Variables Matter

They keep jobs flexible, tidy and safe. Without them, every value would be typed directly into every step.

Imagine a build that deploys to a test server. Without variables, the server address is typed into ten different steps. When the address changes, you must find and fix all ten, and you will surely miss one. With a variable, the address lives in one place, and all ten steps read it. Change it once, and everything follows.

Benefit 1

One place to change

A value defined once and read many times removes copy-and-paste errors and makes updates instant.

Benefit 2

Same job, different settings

The same Pipeline can behave differently for test and production simply by supplying different values, without duplicating the whole job.

Benefit 3

Awareness of context

Jenkins provides facts about the current build, such as its number, branch and workspace, so scripts can name files and messages correctly.

Benefit 4

Safer secrets

Passwords and tokens can be handed to steps as variables during the build, instead of being written into scripts that everyone can read.

Benefit 5

Portable scripts

A script that reads its settings from variables can run on a laptop, a test server and Jenkins, with only the values changing.

Benefit 6

Readable pipelines

Meaningful names such as DEPLOY_TARGET explain intent better than a raw address scattered through the file.

i
Tip

A helpful rule of thumb: if you type the same value in more than two places, or if the value might change, or if it is secret, it probably deserves to be an environment variable.

3Built-in Variables Jenkins Gives You

Before you create anything, Jenkins already places many useful variables in every build.

VariableWhat it holdsA typical use
BUILD_NUMBERThe number of this build, such as 42Naming a package or a report
BUILD_IDA build identifier, in recent versions the same as the numberSimilar uses, mostly for older setups
BUILD_URLThe web address of this build’s pageLinking to the build from a message
BUILD_TAGA text combining the job name and build numberUnique labels for files and images
JOB_NAMEThe full name of the job, including foldersReports and notifications
JOB_BASE_NAMEThe short name of the job without folder pathSafe file names
JOB_URLThe web address of the jobLinking to the job page
WORKSPACEThe absolute folder path where the build worksPointing tools at files inside the workspace
NODE_NAMEThe name of the machine running the buildDebugging differences between agents
NODE_LABELSThe labels of that machineUnderstanding where a build landed
EXECUTOR_NUMBERThe slot number on that machineAvoiding clashes when builds share a machine
JENKINS_URLThe web address of the Jenkins serverBuilding links to other pages
STAGE_NAMEThe name of the current stage in a Declarative PipelineMessages that say which stage is running

Variables added by plugins

Plugins add their own variables. The Git plugin, for example, adds names for the commit being built, the branch and the repository address, typically GIT_COMMIT, GIT_BRANCH and GIT_URL. Multibranch Pipelines add BRANCH_NAME for the branch being built, and for pull requests they add names such as CHANGE_ID and CHANGE_TARGET. These let a Pipeline behave differently for a feature branch than for the main branch, or for a pull request than for a release.

i
Tip

Jenkins keeps a reference page listing the variables available on your installation. On your own server, the Pipeline Syntax help includes a Global Variables Reference, and a page named env-vars.html under the Jenkins address lists the built-in ones. Because plugins vary, the list on your own server is the one that counts.

Analogy

The built-in variables are like the labels a courier company automatically sticks on every parcel: tracking number, sender, destination and date. You did not write them, yet they are always there, and every handler along the route reads them.

4How a Variable Reaches Your Step

A short look at the journey explains why scope and syntax matter so much.

A step often runs on an agent, a worker machine, while the Pipeline is managed by the controller, the brain of Jenkins. When a step starts, Jenkins gathers the variables that apply, places them in the surroundings of the step process, and then starts your command. The command reads them using the syntax of whatever language it uses.

flowchart TD
    A["Operating system variables of the agent"] --> M["Jenkins merges all layers"]
    B["Global and node settings in Jenkins"] --> M
    C["Built-in build variables"] --> M
    D["Pipeline level and stage level definitions"] --> M
    E["Parameters chosen for this build"] --> M
    F["Bound credentials for a block"] --> M
    M --> S["Environment placed around the step process"]
    S --> R["Your command reads the values by name"]
    
Figure 1: Several layers of variables are merged and handed to each step
1

The build starts

Jenkins creates a build and chooses an agent. The machine already has its own operating system variables.

2

Jenkins adds its layers

Global settings, machine settings, built-in build facts, plugin facts and parameters are added on top.

3

Your definitions are applied

Variables you defined in the job, the Pipeline, a stage or a block are added for the steps they cover.

4

The step process starts

Jenkins launches your shell or tool with the merged variables in its surroundings.

5

Your command reads by name

The shell, script or tool looks up each variable it needs, using its own syntax.

Analogy

This is like preparing a kitchen station before a cook starts. Some tools are always there (operating system), the restaurant adds today’s specials (Jenkins layers), the head chef adds special instructions for one dish (your definitions), and only then does the cook begin, reading from all those notes without asking again.

5Ways to Define Your Own Variables

You can create variables at several levels, from the whole server down to a single block of steps.

Where you define itWho can see itGood for
Global setting in JenkinsEvery build on every machineValues shared by everything, such as a company-wide server address
Node (agent) settingEvery build that runs on that machineMachine-specific values, such as the location of a tool on that agent
Freestyle project settingsThat project’s buildsSimple values for one job
Pipeline level environment sectionEvery stage and step of that PipelineValues used throughout one Pipeline
Stage level environment sectionOnly the steps in that stageValues that matter only to one phase
A wrapper step for a blockOnly the steps inside the blockTemporary changes for a few steps
Build parametersThat single build, chosen by the person or triggerValues that differ for each run
Set during the build in a scriptLater steps of the same buildValues computed while running

Global and node-level variables

An administrator can define variables for the whole Jenkins server in the system settings, under an area for global properties. Each agent machine can also carry its own variables in its configuration. Global values are shared by every build. Node values apply only to builds that land on that machine, which is handy when the same tool sits in different folders on different agents.

Freestyle projects

In a Freestyle project, the Build Environment section and parameter settings are the main places. Ticking “This project is parameterized” turns each parameter into an environment variable for the build. Some plugins add options in the Build Environment section for injecting more variables from a file or a list. Use such injection plugins with care and read their security notes, because they can widen who is able to affect a build’s surroundings.

Declarative Pipelines

In a Declarative Pipeline, you use a section named environment. Placed at the top level, it makes the variables available to every stage. Placed inside a stage, it makes them available only to that stage. Each entry is a name and a value, in the form NAME = 'value', and later entries can even use earlier ones. This is the tidiest and most popular way to define variables for a Pipeline.

Wrapper steps and scripts

The withEnv step is a wrapper. It takes a list of name and value pairs and applies them only to the steps inside its block. When the block ends, the variables vanish. In scripted code, you can also assign to the special env object, for example env.RELEASE_TYPE = 'beta', and later steps of the same build will see that value. This is useful when a value is calculated during the build.

!
Warning

Beware of assigning to variables inside script blocks and expecting every parallel branch to agree. If several branches write to the same variable at once, the result depends on timing. Give each branch its own clearly named value.

Analogy

These levels are like notices in a school. A notice on the main gate is read by everyone (global). A notice on one classroom door is read only by that class (stage). A sticker on one student’s desk applies only while they sit there (wrapper block). The closer the notice is to you, the more specifically it applies.

6Scope and Which Value Wins

When the same name is defined in more than one place, Jenkins needs a rule for choosing.

Scope means the area in which a variable is visible. A stage-level variable is visible only inside its stage. A Pipeline-level one is visible everywhere in that Pipeline. A wrapper block gives visibility only inside the block.

The general principle is that the closest definition wins. If a Pipeline defines a variable and one stage defines the same name differently, the steps in that stage see the stage’s value, while the other stages still see the Pipeline’s value. A wrapper block placed inside a stage overrides both, for its steps only.

flowchart TD
    G["Global or node value: REGION is eu"] --> P["Pipeline level: REGION is us"]
    P --> S1["Stage Build: no override, sees us"]
    P --> S2["Stage Deploy: sets REGION to ap"]
    S2 --> W["Inside a wrapper block: REGION is set to sa"]
    W --> V1["Steps inside the block see sa"]
    S2 --> V2["Other Deploy steps see ap"]
    S1 --> V3["Build steps see us"]
    
Figure 2: The closest definition wins, and its effect ends where its scope ends
SituationWhat the step sees
Only a Pipeline-level value existsThat value, in every stage
Pipeline-level and stage-level values differThe stage value inside that stage, the Pipeline value elsewhere
A wrapper block sets the name tooThe block value inside the block only
A parameter and an environment entry share a nameAvoid this. Behaviour is easy to misjudge, so use distinct names
A variable defined only inside a stage is read in a later stageNothing. It is out of scope there
A variable is assigned in a script through the env objectThe new value in later steps of the same build
!
Warning

Do not rely on remembering subtle precedence rules across many layers. Choose unique, descriptive names for each variable, such as DEPLOY_REGION rather than REGION, and avoid defining the same name at several levels. Clear names beat clever knowledge.

7Reading Variables: Syntax Differences

The same variable is read in different ways, depending on where the reading happens. This is the single biggest source of beginner confusion.

Where you read itHow you write the readingExample for the build number
Inside a shell step on Linux or macOSA dollar sign before the name$BUILD_NUMBER
Inside a batch step on WindowsPercent signs around the name%BUILD_NUMBER%
Inside a PowerShell stepA dollar sign and the word env with a colon$env:BUILD_NUMBER
In Pipeline code, the Groovy languageThe env object with a dotenv.BUILD_NUMBER
Inside a double-quoted Pipeline textA dollar sign, filled in by Jenkins before the command starts"Build ${env.BUILD_NUMBER}"
Inside a single-quoted Pipeline textLeft untouched. The shell fills it in later'echo $BUILD_NUMBER'

Who fills in the value: Jenkins or the shell?

This detail deserves a slow explanation. In Pipeline files, text in double quotes is processed by Jenkins first: any ${...} placeholders are replaced with values before the command is even sent to the machine. Text in single quotes is passed exactly as written, and the shell on the machine fills in variables when the command runs. Both work for ordinary values, but they behave differently, and the difference matters greatly for secrets, as we will see next.

sequenceDiagram
    participant P as Pipeline code
    participant J as Jenkins engine
    participant SH as Shell on the agent
    Note over P,SH: Double quotes
    P->>J: Text with a placeholder in double quotes
    J->>J: Replace the placeholder with the value
    J->>SH: Send the finished command with the value inside
    Note over P,SH: Single quotes
    P->>J: Text with a variable in single quotes
    J->>SH: Send the command exactly as written
    SH->>SH: Look up the variable in its own environment
    
Figure 3: With double quotes Jenkins fills in the value, with single quotes the shell does
i
Tip

A safe default: use single quotes for shell commands so the shell reads variables from its environment. Use double quotes only when Jenkins itself needs to build a piece of text, such as a message or a file name, from a value that is not secret.

Analogy

Double quotes are like a secretary who fills in the blanks on a form before handing it to the worker. Single quotes are like handing over the form with blanks still empty, so the worker looks up the answers personally. If the answer is a secret, you would rather the worker fetch it from the locked cabinet than have it written on the form in advance.

8Environment Variables and Secrets

Variables are a convenient way to hand secrets to a step, but only if it is done through the right door.

A secret is a value that must not be seen by everyone: a password, a token or a private key. Jenkins keeps secrets in its credentials store, a protected vault. A plain environment variable is not a vault. Anyone who can read the Pipeline file or the console output can read it. So secrets must come from the credentials store, and be bound into a variable only for the moment they are needed.

Way 1

The credentials helper in an environment section

A Declarative Pipeline can bind a stored credential to a variable name. For a username and password pair, Jenkins creates extra variables for the user and the password parts. Jenkins masks these values in the log.

Way 2

The withCredentials wrapper

Binds a credential to a variable only inside a block, so the secret exists for the shortest possible time. Best for secrets needed by only one or two steps.

Way 3

Credentials binding in Freestyle

A Build Environment option that binds stored credentials to variables for the build.

flowchart LR
    V["Credentials store: protected vault"] -->|bind for a block| E["Environment variable exists only during the block"]
    E --> S["Step reads the variable from its environment"]
    S --> M["Jenkins masks the value if it appears in the log"]
    E -->|block ends| X["Variable disappears"]
    
Figure 4: A secret is bound to a variable for the shortest time needed, and masked in the log

Masking, and its limits

When a secret is bound through the credentials system, Jenkins remembers its value and replaces it with stars if it shows up in the console output. This is a valuable safety net, but it is not perfect. A secret that is changed, encoded, split into pieces or embedded in a longer text may slip through unmasked. And secrets that Jenkins never knew were secrets, such as a password typed directly into a script or a plain variable, are not masked at all.

!
Warning

Using double quotes around a secret variable in a Pipeline makes Jenkins substitute the actual value into the command text itself, before the command runs. Jenkins warns about this because the value can then leak into logs, process lists and error messages. Use single quotes so that the shell reads the secret from its environment instead.

Habits that keep secrets safe

  • Never type secrets into environment sections or scripts. Reference the credentials store instead.
  • Bind as narrowly as possible. Use a wrapper block around only the steps that need the secret.
  • Never print all variables. A command that lists the whole environment can reveal secrets that were not masked.
  • Turn off command echoing near secrets. Shell steps normally print each command, so keep secret handling in scripts that do not echo them.
  • Assume anything in a log is visible to your whole team. Logs are stored, shipped and pasted into chats.
  • Rotate anything that leaks. Replace the secret immediately.
Analogy

Binding a secret is like borrowing a key from a locked cabinet. You sign it out, use it for one task, and hand it back straight away. You never copy the key, stick it on the whiteboard, or shout its number across the room.

9Environment Variables, Parameters and Credentials Compared

Three ideas are often confused. Knowing the difference tells you which one to pick.

IdeaWho supplies the valueWhen it is decidedBest for
Environment variableThe Pipeline author, an administrator or Jenkins itselfWhen the job is written or configuredFixed settings, shared constants, build facts
ParameterThe person or trigger starting the buildAt the moment the build startsChoices that differ from run to run, such as a version or a target
CredentialThe credentials store, managed by administratorsStored beforehand, bound when neededSecrets such as passwords, tokens and keys
flowchart TD
    N["I need a value in my build"] --> Q1{"Is it secret?"}
    Q1 -->|Yes| C["Use the credentials store and bind it"]
    Q1 -->|No| Q2{"Does it change with each run?"}
    Q2 -->|Yes| P["Use a build parameter"]
    Q2 -->|No| Q3{"Is it shared by many jobs?"}
    Q3 -->|Yes| G["Use a global or node level variable"]
    Q3 -->|No| E["Use a Pipeline or stage environment section"]
    
Figure 5: A short decision path for choosing where a value should live

A parameter is like a question Jenkins asks before the build starts, such as “Which version should I build?” Once answered, its value is also made available as an environment variable, so your shell steps can read it by name, and Pipeline code can read it through the params object. So parameters and environment variables work together: parameters are one way that values arrive, and environment variables are one way they are read.

Analogy

An order form at a restaurant shows the difference. The printed menu prices are fixed (environment variables). The choices the customer ticks, such as size and toppings, differ per order (parameters). The card payment details go into a secure terminal, not onto the paper (credentials).

10Passing Values Between Stages and Steps

Variables can carry information from one part of a build to another, but you must use the right method.

Sometimes a step discovers a fact that later steps need, such as a version number read from a file, or the name of a newly created resource. There are two common ways to pass it on.

Way 1

Assign to the env object

In a script block, set a new value on the special env object. Later steps of the same build, in any stage, can read it. Good for computed values.

Way 2

Capture command output

Ask a command step to return the text it printed, then store that text in a variable. Useful for reading versions and paths.

Two limits are worth knowing. First, a variable set by a shell command using the shell’s own syntax lives only inside that one shell process. When the step ends, the process ends, and the value is gone. The next step starts a fresh shell that knows nothing about it. This surprises nearly everyone at first. To keep a value, hand it back to Jenkins as a return value, then place it on the env object.

Second, the variables set inside a withEnv block or a stage environment section do not survive beyond their scope. Design each stage so that it does not depend on hidden leftovers from an earlier one.

sequenceDiagram
    participant S1 as Step 1 shell process
    participant J as Jenkins env object
    participant S2 as Step 2 shell process
    S1->>S1: Set a variable using shell syntax
    Note over S1: Value exists only inside this process
    S1-->>J: Process ends, the value is lost
    J->>S2: Start a new shell with the Jenkins environment
    S2->>S2: The shell variable from step 1 is not there
    Note over J,S2: To keep a value, return it to Jenkins and store it on the env object
    
Figure 6: A variable set inside one shell step does not survive into the next step
i
Tip

If a later stage needs a value, treat it as data to hand over deliberately. Return it from the step that found it, store it on the env object, and read it in the later stage. Deliberate hand-overs are easy to follow and debug.

Analogy

A shell process is like a temporary workbench that is cleared away when the job ends. Anything you scribbled on it disappears. To keep a note for the next worker, you must pin it to the shared board, which in Jenkins is the env object.

11Variables Across Agents, Containers and Parallel Branches

The place where a step runs changes what it sees. This matters more as your setup grows.

Different agents, different surroundings

Each agent has its own operating system variables. A tool folder that exists on one machine may be missing from another, and the search path may differ. Variables from Jenkins itself, such as the build number, are the same everywhere, but machine facts differ. This is why a build can work on one agent and fail on another: a variable the step relied on is set differently on each.

Containers

When a step runs inside a container, the container has its own separate environment. Jenkins passes along some of its build variables, but the container’s own variables come from its image and settings. Treat a container as a fresh room: anything the tools inside need must be provided explicitly. In return, containers give you a big benefit, because every run starts from exactly the same surroundings.

Parallel branches

When stages run in parallel, each branch may run on a different agent, with its own surroundings. Variables defined at the Pipeline level are visible to all of them. But values assigned during the build by one branch are not a safe way to pass information to another branch, because their timing is unpredictable. Give each branch its own variables, and gather results at the end.

SituationWhat can go wrongSafer approach
Different agentsTool locations or search paths differSet tool variables per node, or use containers for identical surroundings
Inside containersExpected variables are missing inside the containerPass needed variables explicitly and keep images consistent
Parallel branchesBranches overwrite each other’s shared valuesUse branch-specific names and collect results after the branches finish
Long PipelinesMany overlapping definitions confuse readersDefine once at the top, and keep stage-level overrides rare
!
Warning

Never assume the agent’s operating system variables are the same on every machine. If your step depends on a tool location or a version, either set it deliberately in the Pipeline or verify it at the start of the build, so failures explain themselves.

12Advantages, Disadvantages and Trade-offs

Environment variables are simple and useful, and they come with a few costs.

Advantages

  • Very simple: a name and a text value.
  • Supported by every language and tool.
  • One place to change a value used in many steps.
  • Jenkins supplies many useful facts for free.
  • Works at global, machine, job, stage and block levels.
  • Makes scripts portable between laptops and Jenkins.

Disadvantages and costs

  • Values are text only, so numbers and lists need conversion.
  • Too many layers make it hard to know which value applies.
  • Plain variables are visible in files and logs, so they are unsafe for secrets.
  • Quoting rules are subtle and easy to get wrong.
  • Values do not travel across shell steps by themselves.
  • Machine-specific values can cause “works on one agent” bugs.

The main trade-off is convenience versus clarity. Variables make a Pipeline flexible, but every extra layer makes it harder to see what a step will actually receive. Aim for a small number of well-named variables, defined in as few places as possible.

A good variable has one clear name, one clear home, and one clear job.

13Troubleshooting Common Problems

Most variable problems are of the same few kinds. Recognise the symptom, and the fix is usually short.

SymptomLikely causeWhat to try
The variable prints as emptyIt is not defined in that scope, or the name is misspelledCheck the spelling and capital letters, and check that the definition covers this step
The variable prints as the literal name, with a dollar signWrong syntax for where it is read, for example shell syntax used in Pipeline codeUse the syntax that matches the place: shell, batch or Pipeline code
Works in one stage, missing in the nextThe value was set in a stage-level section or a shell process, and went out of scopeDefine it at the Pipeline level, or store it on the env object
Works on one agent but not anotherDifferent operating system variables or tool locationsPrint relevant variables, and set the values explicitly in the job
Windows step sees nothingShell syntax used in a batch stepUse percent signs, or the PowerShell form
A secret appears in the logIt was not bound through credentials, or it was transformed before printingBind properly, use single quotes, and rotate the leaked secret
A value has a stray newline or spaceCaptured command output includes trailing whitespaceTrim the captured text before storing it
A number does not compare correctlyAll variable values are textConvert to a number before doing arithmetic or comparisons
A variable seems to have two different valuesThe same name is defined at several levelsRename to unique names, and remove duplicate definitions
1

Print only what you need

Print the single variable in question, not the whole environment, to avoid exposing secrets.

2

Check the syntax for the place

Shell, batch, PowerShell and Pipeline code each read variables differently.

3

Check the scope

Is the step inside the stage, block or Pipeline where the variable was defined?

4

Check the machine

Which agent ran the step, and does it differ from a machine where it worked?

5

Compare with a good build

Open the console output of a working build and compare the values it shows.

!
Warning

The classic beginner trap is printing the entire environment “just to see everything”. Anything not properly masked, including tokens that were passed as plain variables, ends up in the log. Print only the specific variable you are investigating.

14Design Patterns and Anti-patterns

A pattern is a proven habit. An anti-pattern is a tempting shortcut that causes trouble later.

Patterns worth copying

Pattern

Define once at the top

Declare shared values in one environment section at the start of the Pipeline, so readers see all settings in one place.

Pattern

Descriptive names

Use names such as DEPLOY_TARGET or ARTIFACT_VERSION, in capital letters with underscores, so purpose is obvious.

Pattern

Secrets only from the vault

Bind credentials for the smallest block, and never type secret values into files.

Pattern

Parameters for per-run choices

Use parameters for values a person chooses at build time, and environment sections for fixed values.

Pattern

Validate early

Check at the start that required variables exist and look sensible, and fail with a clear message if not.

Pattern

Thin steps, script reads variables

Let scripts in your repository read their settings from variables, so they run the same on a laptop and in Jenkins.

Anti-patterns to avoid

ANTI-PATTERN 01Avoid
What people do

They put passwords and tokens directly into an environment section or a global variable.

Why it hurts

Anyone who can read the Jenkinsfile, the job configuration or the logs can read the secret, and copies spread it further.

Better approach

Store the secret in the credentials store and bind it only where needed.

ANTI-PATTERN 02Avoid
What people do

They print the whole environment on every build for convenience.

Why it hurts

Logs fill with noise and any unmasked secret is exposed to everyone who can read them.

Better approach

Print only the specific variables you need, and only while investigating.

ANTI-PATTERN 03Avoid
What people do

They define the same name at global, node, Pipeline and stage levels.

Why it hurts

Nobody can tell which value a step will get, and a change in one place has surprising effects elsewhere.

Better approach

Use unique names and define each variable in exactly one place.

ANTI-PATTERN 04Avoid
What people do

They rely on hidden machine settings, such as a variable that exists only on one agent.

Why it hurts

Builds pass on one agent and fail on another, and new agents must be tuned by hand.

Better approach

Set required values explicitly in the job, or use containers so surroundings are identical everywhere.

15Best Practices and Common Mistakes

A few steady habits keep your variables tidy, predictable and safe.

Best practices

  • Use clear, unique names. Capital letters with underscores are the common convention.
  • Define each variable in one place. Avoid the same name at several levels.
  • Keep secrets in the credentials store. Bind them narrowly and mask them.
  • Prefer single quotes for shell commands. Let the shell read variables from its environment.
  • Use parameters for run-time choices. Use environment sections for fixed settings.
  • Validate required values early. Fail with a friendly message rather than a mysterious error later.
  • Document each variable. A short comment explains purpose and expected format.
  • Remember values are text. Convert before comparing or calculating.
  • Print selectively. Never dump the whole environment into a log.
  • Keep the Jenkinsfile in version control. Changes to variables are then reviewed like any other change.

Common mistakes

!
Mistake

Using the wrong reading syntax for the place. A dollar sign works in a Linux shell step but not in a Windows batch step, and Pipeline code uses the env object. Match the syntax to the place.

!
Mistake

Expecting a shell step’s variable to survive to the next step. Each shell step is a separate process. Return the value to Jenkins and store it deliberately.

!
Mistake

Trusting a value without checking. A missing variable often appears as an empty string, and a command with an empty value may do something dangerous, such as removing the wrong folder. Validate before using it in destructive commands.

!
Mistake

Building file paths by hand instead of using the workspace variable. Hard-coded paths break when the job runs on a different agent or a different folder. Start from the workspace variable.

16Real-World Usage Patterns

Here is how teams use environment variables in everyday delivery work.

Naming and tagging builds

A team names every package and container image with the build number and the short commit fingerprint, both read from built-in variables. Any file found later can be traced straight back to the exact build and code that made it.

One Pipeline, three environments

A single Pipeline deploys to test, staging and production. A parameter chooses the target, and small lookup values, held as variables, supply the right server address for each. The steps are identical, and only the values differ, which keeps environments consistent.

Branch-aware behaviour

Using the branch name variable, a multibranch Pipeline runs quick checks on feature branches, full tests on the main branch, and a deployment only for release branches. One file serves every branch, and behaviour follows the branch.

Machine-specific tool locations

An organisation keeps tools in different folders on Linux and Windows agents. Each agent defines a variable holding its own tool folder, and jobs read that variable, so the same Pipeline works on both without change.

Safe cloud deployment

A deployment step needs a cloud access key. The team stores it in the credentials store and binds it for only that step. The key lives as a variable for seconds, is masked in the log, and never appears in the repository.

Notification messages

A failure message sent to team chat includes the job name, build number and build address, all read from built-in variables. Anyone reading the message can click straight through to the failing build.

17Frequently Asked Questions

Q1What is an environment variable in Jenkins, in one sentence?
It is a named text value placed in the surroundings of a build step, so commands and scripts can read it by name, such as the build number, a target server or a bound secret.
Q2Which variables does Jenkins provide automatically?
Many, including the build number, build address, job name, workspace folder, node name and Jenkins address. Plugins add more, such as the commit and branch from Git, and the branch and pull request details from multibranch jobs. Your own server lists the available ones in the Pipeline Syntax help and on the env-vars page.
Q3How do I define my own variable in a Pipeline?
Use the environment section of a Declarative Pipeline, at the top for every stage or inside a stage for that stage only. You can also use the withEnv wrapper for a block, or assign to the env object in a script.
Q4Why is my variable empty?
Usually the name is misspelled, the syntax does not match the place where it is read, or the variable is out of scope. Check spelling and capital letters, the reading syntax, and whether the step is inside the stage or block where it was defined.
Q5What is the difference between an environment variable and a parameter?
An environment variable is a value defined by the job author or by Jenkins. A parameter is a value chosen by the person or trigger when the build starts. Parameters are also made available as environment variables, so both can be read by name.
Q6Is it safe to store passwords in environment variables?
Not as plain text in a Jenkinsfile or a job setting. Store the secret in the credentials store and bind it to a variable only for the block that needs it. Jenkins then masks the value in logs.
Q7Why should I use single quotes around shell commands?
With double quotes, Jenkins substitutes the value into the command text itself before running it, which can expose secrets. With single quotes, the shell reads the variable from its own environment, which is safer for secrets and behaves consistently.
Q8Why does a variable set in one shell step not exist in the next?
Each shell step runs in its own separate process, and that process ends with the step. To keep a value, return it from the step to Jenkins, store it on the env object, and read it in later steps.
Q9Are all variable values text?
Yes. Even numbers arrive as text. Convert them before doing arithmetic or numeric comparisons, and remember that a true or false value is also just text.
Q10Can I list all variables of a build?
You can, but be careful. Listing everything can reveal secrets that are not masked. Print only the specific variables you are investigating, and avoid leaving full listings in production jobs.
Q11How do variables work with parallel stages and containers?
Pipeline-level variables are visible to all branches. Branches may run on different agents with different machine variables, and containers have their own environments, so pass needed values explicitly and give each branch its own variable names.

18Summary and Key Takeaways

Environment variables are the shared whiteboard of a Jenkins build: labelled pieces of text that any step can read by name. Jenkins fills the board with useful facts, such as the build number, the workspace and the branch, and lets you add your own at the level of the server, the machine, the job, the stage or a single block of steps.

Using them well comes down to a few clear habits. Choose unique, descriptive names and define each one in a single place. Remember that values are text, that scope decides visibility, and that the closest definition wins. Use the right syntax for the place where you read the value, and prefer single quotes in shell commands. Keep secrets in the credentials store and bind them narrowly. With those habits, variables make your Pipelines flexible, portable and safe.

Key Takeaways

  • An environment variable is a named text value that steps can read, and Jenkins provides many for free, such as build number, job name, workspace, node name and, with plugins, commit and branch.
  • Define your own at the right level: global or node settings, a Freestyle project, a Pipeline or stage environment section, a withEnv block, or the env object in a script.
  • Scope decides visibility, and the closest definition wins. Use unique names and define each variable in one place to avoid confusion.
  • Syntax depends on where you read it: dollar sign in a Linux shell, percent signs in a Windows batch step, and the env object in Pipeline code.
  • Prefer single quotes for shell commands, so the shell reads values from its environment rather than Jenkins pasting them into the command text.
  • Keep secrets in the credentials store, bind them for the smallest block, never print the whole environment, and rotate anything that leaks.
  • Values do not travel between shell steps by themselves. Return a value to Jenkins and store it on the env object to keep it, and remember that all values are text.