Docker "ARG used before FROM not allowed" build error in CI
An ARG declared before the first FROM is global: it can parameterize the FROM line, but it is out of scope inside the build stage unless you re-declare it. Builds that expect a pre-FROM ARG to be visible in RUN steps see an empty value.
What this error means
A pre-FROM ARG reads as empty inside a stage, or a base-image tag built from it resolves wrong. The ARG was never re-declared after FROM.
# ARG VERSION=1.21 declared before FROM
FROM golang:${VERSION}
RUN echo "building ${VERSION}" # VERSION is empty hereCommon causes
A global ARG not re-declared inside the stage
ARGs before the first FROM are only in scope for FROM lines; inside the stage they must be re-declared with ARG NAME to be visible.
Expecting one ARG to span all stages
Each build stage has its own ARG scope; a global ARG does not automatically flow into every stage body.
How to fix it
Re-declare the ARG after FROM
- Declare the global ARG before FROM to parameterize the image.
- Re-declare
ARG VERSIONinside the stage so RUN steps can read it.
ARG VERSION=1.21
FROM golang:${VERSION}
ARG VERSION
RUN echo "building ${VERSION}"Re-declare in every stage that needs it
- Add an
ARG NAMEline at the top of each stage body that references it.
ARG VERSION=1.21
FROM golang:${VERSION} AS build
ARG VERSION
FROM alpine
ARG VERSION
RUN echo "${VERSION}"How to prevent it
- Re-declare global ARGs inside each stage that uses them.
- Keep the FROM-line ARG and the in-stage ARG names aligned.
- Lint for ARG scope issues with hadolint.