Skip to content
Latchkey

Docker "target stage could not be found" - Fix Multi-Stage Builds

You asked BuildKit to build (or copy from) a named stage that the Dockerfile does not define. The stage name in the command and the AS <name> in the file disagree.

What this error means

A build with --target <name>, or a COPY --from=<name>, fails with target stage "<name>" could not be found. The Dockerfile builds fine without the target.

docker build output
ERROR: failed to solve: target stage "prod" could not be found
# Dockerfile defines: FROM nginx AS production  (not "prod")

Diagnose it: build context, cache, or platform?

A Dockerfile that builds locally and fails in CI usually differs in one of three ways: the build context contains different files, the layer cache is cold or poisoned, or the runner architecture does not match what the base image provides.

Terminal
# what is actually being sent as build context (dockerignore applies)
docker build --no-cache --progress=plain -t probe . 2>&1 | head -40

# what platform are you on, and what does the base image support?
docker version --format '{{.Server.Arch}}'
docker buildx imagetools inspect <base-image> | grep -i platform

# prove it is not a cache artefact
docker build --no-cache .

Common causes

Typo or mismatch in the stage name

The --target/--from value does not exactly match a FROM ... AS <name> in the Dockerfile (e.g. prod vs production).

The stage is not defined in this Dockerfile

You referenced a stage that exists in a different Dockerfile, or was renamed/removed, so it is absent from the one being built.

How to fix it

Match the target to a defined stage

Name stages explicitly and reference them by the exact same name.

Dockerfile / Terminal
FROM node:20 AS build
# ...
FROM nginx:alpine AS production
# build it:
docker build --target production -t api .

List the stages in the Dockerfile

Grep the stage names so the target is unambiguous.

Terminal
grep -niE '^FROM .* AS ' Dockerfile

Keep the build context small and deterministic

  • A missing .dockerignore sends node_modules, .git, and build output to the daemon, which is slow and can change layer hashes between environments.
  • A COPY of a path that exists locally but is gitignored will fail in CI, because the runner only has what the checkout produced.
  • Multi-arch builds need buildx and QEMU set up explicitly; a plain docker build on an ARM runner silently produces an ARM image.

How to prevent it

  • Keep stage names consistent between the Dockerfile and CI commands.
  • Reference stage names from a single variable where possible.
  • Lint for COPY --from references that name a non-existent stage.

Frequently asked questions

What causes Docker "target stage could not be found"?
There are 2 common causes: typo or mismatch in the stage name and the stage is not defined in this dockerfile. The --target/--from value does not exactly match a FROM ...
How do I fix Docker "target stage could not be found"?
There are 2 fixes depending on which cause you have: match the target to a defined stage and list the stages in the dockerfile. Work through them in order, since the first is the most common.
What does Docker "target stage could not be found" actually mean?
A build with --target <name>, or a COPY --from=<name>, fails with target stage "<name>" could not be found.
How do I stop Docker "target stage could not be found" happening again?
Keep stage names consistent between the Dockerfile and CI commands. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card