Fix --mount=type=cache with onbuild steps
James McDonnell
We are using a shared image the cache mount in the dockerfile:
ONBUILD RUN --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
apt update ...
This image is then used as the root image in another dockerfile.
When this second docker image is build, it fails because of:
failed to solve: cannot mount from stage "scratch" to "/var/lib/apt/lists", stage needs to be defined before current command
A work around was found by defining
FROM scratch as scratch
and FROM parent as parent
in the child docker image, but this is cumbersome. The build should work just like it does locally.Jasmine
This issue happens because ONBUILD doesn’t fully support BuildKit features like --mount=type=cache, so the child build lacks the proper stage context and fails. A better approach is to move the cache mount logic directly into the child Dockerfile where it’s fully supported. I came across a similar fix explained here https://bombituppro.app/ which helped simplify the build process and avoid such errors.
silverrates rates
This issue seems to be caused by how ONBUILD instructions interact with cache mounts in multi-stage Docker builds. When the child image is built, Docker tries to execute the inherited RUN --mount=type=cache step, but at https://bombituppro.app point the proper build stage context is not fully established, which leads to the “scratch stage” error. That’s why manually defining FROM scratch and the parent image works, even though it feels redundant. A better and cleaner solution would be to avoid using ONBUILD for cache-mounted commands and instead define those steps directly in the final Dockerfile for more predictable and stable builds.
Muslim
It looks like the issue is coming from how ONBUILD interacts with BuildKit mounts. The --mount=type=cache directive doesn’t always behave as expected in inherited stages, especially when the base image doesn’t explicitly define a usable stage before the mount is referenced.
Instead of relying on ONBUILD for cache mounts, you might get more consistent results by moving that logic directly into the child Dockerfile or defining a proper named stage in the parent image. That way, BuildKit can resolve the cache mount without hitting the “stage needs to be defined” error.
I ran into something similar while experimenting with optimized builds and found a few unconventional workarounds explained in this guide on https://thetruecaler.com/ it’s not directly about Docker, but the caching and build-step tricks discussed there gave me a different perspective on handling layered processes.
Muslim
This issue happens because ONBUILD doesn’t properly handle advanced BuildKit features like --mount=type=cache when passed to child images, causing the stage context error. A more reliable fix is to move the cache mount into the child Dockerfile or explicitly define build stages with aliases instead of relying on inherited steps. This keeps the build process predictable and avoids the “scratch” stage conflict. I came across a similar case and found a clear explanation with practical fixes here https://tmsim.ph
, which really helped simplify the approach.
Muslim
This error usually happens because ONBUILD doesn’t properly preserve the cache mount context when the child image is built, especially with BuildKit. Instead of relying on ONBUILD for cache layers, it’s often more stable to move those steps directly into the child Dockerfile using a proper multi-stage setup, which avoids the “scratch” mounting issue entirely. I faced something similar and found that restructuring the build process gave more consistent results across environments. There’s also a simple explanation of this kind of issue on https://gtasandresapk.com/ that helped me understand why this happens and how to avoid it.
A
Alice Sphere
It seems like you're encountering a common issue with the cache mount in ONBUILD steps. Defining the stages explicitly, as you've done, is a workaround, but it can indeed be cumbersome. Have you considered using a multi-stage popular games build with a defined base image for better compatibility? This might simplify your Dockerfile and avoid the mounting issue. Let us know if you need further assistance!
A
Alicent Hightower
@Slope Game Hey James - yeah, this is a frustrating quirk with how CircleCI handles ONBUILD and cache mounts. That workaround with naming the stages works, but it really shouldn’t be necessary if it just behaved like a local Docker build.