How to fix ARG variable is undefined in Docker
This Docker build error occurs when you reference an ARG variable that hasn't been declared, or when the ARG declaration loses scope due to multi-stage builds. Fix it by declaring ARG before use and redeclaring after each FROM instruction.
Quick fix
Fixes ARG variable is undefined
FROM alpine AS base
COPY $foo .- Declare ARG before using it
- Redeclare ARG after each FROM in multi-stage builds
- Handle ARG in FROM instructions correctly
- Pass build arguments when building
FROM alpine AS baseCOPY $foo .ARG variable is undefined
What this error means
The "ARG variable is undefined" error in Docker indicates that you're trying to use a build argument that hasn't been properly declared or has gone out of scope. Docker's ARG instruction defines variables that users can pass at build-time using the `--build-arg` flag. This error commonly occurs in two scenarios: when you reference a variable before declaring it with ARG, or when you use multi-stage builds where each FROM instruction resets the scope of previously declared ARGs. Unlike ENV variables which persist throughout the build and into the running container, ARG variables are only available from the point they're declared until the next FROM instruction. Docker BuildKit performs stricter validation of undefined variables than the legacy builder. When BuildKit detects usage of an undeclared variable, it warns you with messages like "Usage of undefined variable '$foo'" to help catch typos and missing declarations early in the build process.
Typical symptoms
- Build warning: 'Usage of undefined variable' followed by the variable name
- Variable substitution results in empty string instead of expected value
- COPY or ADD instructions fail with empty source paths
- RUN commands fail because expected environment values are empty
- Multi-stage builds work in first stage but ARG values disappear in subsequent stages
- Docker build succeeds but application fails at runtime due to missing configuration
Common causes
- ARG variable referenced before being declared with ARG instruction
- Multi-stage build where ARG was declared before FROM but not redeclared after
- Typo in variable name when referencing (e.g., $PAHT instead of $PATH)
- Using ARG in FROM instruction without declaring it before FROM
- Passing --build-arg for a variable that isn't declared in Dockerfile
- ENV variable with same name overriding the ARG value
- Missing --build-arg flag when running docker build for required arguments
How to fix "ARG variable is undefined"
Every ARG variable must be declared before it's used. Add an ARG instruction before any reference to the variable.
Incorrect:
FROM alpine AS base
COPY $foo .Correct:
FROM alpine AS base
ARG foo
COPY $foo .You can also provide a default value:
FROM alpine AS base
ARG foo=default_value
COPY $foo .In multi-stage builds, each FROM instruction starts a new build stage and resets the scope of ARG variables. You must redeclare the ARG in each stage where you need it.
Problem - ARG loses scope after FROM:
ARG VERSION=latest
FROM ubuntu:${VERSION}
# VERSION is still available here for FROM
ARG FILENAME
COPY ${FILENAME} /app/
# FILENAME works in this stage
FROM alpine
# FILENAME is now undefined here!
COPY ${FILENAME} /app/ # This failsSolution - Redeclare ARG in each stage:
ARG VERSION=latest
FROM ubuntu:${VERSION} AS builder
ARG FILENAME
COPY ${FILENAME} /app/
RUN build-something
FROM alpine
ARG FILENAME
COPY ${FILENAME} /app/The redeclared ARG inherits the value from --build-arg automatically.
If you need to use an ARG in a FROM instruction (like for dynamic base images), declare it before the FROM:
# Declare ARG before FROM
ARG ALPINE_VERSION=3.20
FROM alpine:${ALPINE_VERSION}
# If you need the value after FROM, redeclare it
ARG ALPINE_VERSION
RUN echo "Using Alpine ${ALPINE_VERSION}"Note that the ARG declared before FROM is only available in the FROM instruction itself. To use it in subsequent instructions, you must redeclare it after FROM.
Make sure to pass the required build arguments using the --build-arg flag:
# Single argument
docker build --build-arg FILENAME=app.tar.gz -t myapp .
# Multiple arguments
docker build \
--build-arg VERSION=1.0.0 \
--build-arg ENV=production \
-t myapp .If you don't pass a value and there's no default, the ARG will be empty (not undefined, but empty string).
Using docker-compose:
services:
app:
build:
context: .
args:
- VERSION=1.0.0
- ENV=productionDocker BuildKit can detect typos and suggest corrections. If you see a message like:
Usage of undefined variable '$PAHT' (did you mean $PATH?)Review your Dockerfile for spelling mistakes:
# Wrong
ARG MY_VARIABLE
RUN echo ${MY_VARAIBLE} # Typo!
# Correct
ARG MY_VARIABLE
RUN echo ${MY_VARIABLE}Use consistent naming conventions (e.g., all uppercase for ARG names) to reduce typo risk.
Environment variables defined with ENV always override ARG instructions with the same name. This can cause unexpected behavior:
FROM alpine
ARG MY_VAR=from_arg
ENV MY_VAR=from_env
# MY_VAR will always be "from_env", not what you pass via --build-arg
RUN echo ${MY_VAR}Solution: Use different names for ARG and ENV, or explicitly set ENV from ARG:
FROM alpine
ARG BUILD_VERSION=1.0.0
ENV APP_VERSION=${BUILD_VERSION}
RUN echo "Build version: ${BUILD_VERSION}"
RUN echo "App version: ${APP_VERSION}"Always provide sensible default values for ARG instructions that should work without --build-arg:
FROM node:18
# Required arg - will be empty if not provided
ARG APP_ENV
# Optional args with defaults
ARG NODE_ENV=production
ARG PORT=3000
ARG LOG_LEVEL=info
ENV NODE_ENV=${NODE_ENV}
ENV PORT=${PORT}
ENV LOG_LEVEL=${LOG_LEVEL}For truly required arguments, add validation:
ARG REQUIRED_VAR
RUN test -n "${REQUIRED_VAR}" || (echo "REQUIRED_VAR must be set" && exit 1)Advanced notes
ARG vs ENV Scope:
- ARG: Available only during build, from declaration point until next FROM (or end of Dockerfile)
- ENV: Available during build (after declaration) AND at container runtime
- ARG values are NOT accessible in running containers unless explicitly copied to ENV
BuildKit UndefinedVar Check:
Docker BuildKit includes a build check called UndefinedVar that validates variable declarations. It doesn't evaluate undefined variables in RUN, CMD, and ENTRYPOINT instructions using shell form, since the shell resolves those. The check helps catch typos early by suggesting similar variable names.
Predefined ARGs:
Docker has predefined ARGs that don't require declaration: HTTP_PROXY, HTTPS_PROXY, FTP_PROXY, NO_PROXY, and their lowercase variants. These can be used without declaring them first:
FROM alpine
RUN wget --proxy=${HTTP_PROXY} http://example.com/fileSecurity Considerations:
Never pass secrets via ARG - they're visible in image history and build logs. Use Docker BuildKit's secret mounts instead:
# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecretdocker build --secret id=mysecret,src=./secret.txt .Frequently asked questions
- What does "ARG variable is undefined" mean?
- The "ARG variable is undefined" error in Docker indicates that you're trying to use a build argument that hasn't been properly declared or has gone out of scope. Docker's ARG instruction defines variables that users can pass at build-time using the --build-arg flag. This error commonly occurs in two scenarios: when you reference a variable before declaring it with ARG, or when you use multi-stage builds where each FROM instruction resets the scope of previously declared ARGs.
- How do I fix "ARG variable is undefined"?
- This Docker build error occurs when you reference an ARG variable that hasn't been declared, or when the ARG declaration loses scope due to multi-stage builds. Fix it by declaring ARG before use and redeclaring after each FROM instruction.
- What causes "ARG variable is undefined"?
- ARG variable referenced before being declared with ARG instruction Multi-stage build where ARG was declared before FROM but not redeclared after Typo in variable name when referencing (e.g., $PAHT instead of $PATH)
- Is the "ARG variable is undefined" error serious?
- It is a low-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Docker Official Documentation
- ๐Docker Docs: UndefinedVar Build Check(Official Docs)
- ๐Docker Docs: Build Variables(Official Docs)
- ๐
- ๐
- ๐