Fix Buildx Export Errors: Enable Docker Containerd
Краткое содержание
Pixel’s announcement explains why Docker Buildx can reject CI builds using --load with a manifest-list error, even when the message never mentions containerd. It covers the classic image store, provenance and SBOM attestations, and how enabling the containerd image store can allow OCI-based loading.
DEV Community
Docker containerd image store not enabled in CI
Docker containerd image store not enabled is the real condition behind a buildx refusal that never mentions containerd, because buildx decides by reading one field in docker info and reports only the consequence. The same refusal fires for a single-platform build that carries attestations, which is why it can appear the day you turn provenance on. Buildx looks for a driver-type of io.containerd.snapshotter.v1 in docker info. With it, the docker exporter is quietly swapped for the OCI one and the load works. What this error means A docker buildx build --load fails immediately, before any build step runs, with a sentence about the docker exporter and manifest lists. Nothing in it names containerd, the image store, or a setting you could change. The same command with --push instead of --load succeeds, which sends people looking at the registry. A second wording exists for builds that write a tar file. The block below sets both out as the two programs that emit them format them, because no run is recorded for this page. ```Both wordings as buildx formats them, not a recorded run --- buildx refused this before the build started ERROR: docker exporter does not currently support exporting manifest lists --- same build with --output type=docker,dest=image.tar ERROR: docker exporter does not support exporting manifest lists, use the oci exporter instead
Common causes
The daemon is using the classic image store
The classic store holds one platform per image, so it has no way to keep a manifest list locally. Buildx knows this from the driver status and refuses rather than building something it cannot import. Most Linux CI runners ship this way unless the daemon configuration says otherwise.
Attestations were turned on and nobody changed the platform list
Provenance and SBOM attestations are described in a format the docker exporter cannot carry, so buildx treats a build with attestations the same way it treats a multi-platform build. In our experience this is the confusing one, because the message talks about manifest lists and the workflow only ever built one platform.
The build writes a tar file rather than loading
When an output destination is set, buildx cannot substitute the OCI importer, because there is nothing to import into. That path refuses on both image stores and says so in different words, naming the oci exporter as the alternative. Enabling the containerd store does not help here.
The setting was applied but the daemon was not restarted
The image store is chosen when the daemon starts. Writing the feature flag into the daemon configuration file changes nothing until the daemon reads it again, and a job that edits the file and immediately builds will see the old store. The check in the step above will say so plainly.
How to fix it
Turn on the containerd snapshotter for the job
- Write the feature flag into the daemon configuration file on the runner.
- Restart the daemon and wait for it to come back before the next step.
- Assert the driver status shows the containerd snapshotter, so a silent failure to restart fails loudly instead.
```.github/workflows/ci.yml
- name: Enable the containerd image store
run: |
echo '{ "features": { "containerd-snapshotter": true } }' \
| sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
timeout 60 bash -c 'until docker info >/dev/null 2>&1; do sleep 2; done'
docker info --format "{{json .DriverStatus}}" | grep -q snapshotter \
|| { echo "::error::containerd image store did not come up"; exit 1; }
Or stop asking for a local multi-platform image Most pipelines load an image only to run tests against it, and tests run on one architecture at a time. Load the platform the job will actually use and push the full set separately. This is the cheaper fix and it survives a runner image change. docker buildx build --platform linux/amd64 --load -t acme/api:test .
docker buildx build --platform linux/amd64,linux/...

Powered by Readybot.io