--- title: "Fix: Docker buildx cache 400 error on CI builds" description: "Stale buildx_buildkit_builder containers on Gitea Actions runner cause 400 Bad Request when exporting cache to Docker Hub." type: troubleshooting domain: development tags: [troubleshooting, docker, gitea, ci] --- # Fix: Docker buildx cache 400 error on CI builds **Date:** 2026-03-23 **Severity:** Medium — blocks CI/CD Docker image builds, requires manual intervention to retrigger ## Problem Gitea Actions Docker build workflow fails at the "exporting cache to registry" step with: ``` error writing layer blob: failed to copy: unexpected status from PUT request to https://registry-1.docker.io/v2/.../blobs/uploads/...: 400 Bad request ``` The image never gets pushed to Docker Hub. Seen on both Paper Dynasty and Major Domo repos. ## Root Cause Stale `buildx_buildkit_builder-*` containers accumulate on the Gitea Actions runner host. Each CI build creates a new buildx builder instance but doesn't always clean up. Over time, these stale builders corrupt the registry cache state, causing Docker Hub to reject cache export PUT requests with 400. ## Fix Kill all stale buildx builder containers on the runner, then retrigger the build: ```bash # Kill stale builders ssh gitea "docker rm -f \$(docker ps -a --format '{{.Names}}' | grep buildx_buildkit_builder)" # Retrigger by deleting and re-pushing the tag git push origin :refs/tags/ && git push origin ``` ## Lessons - Monitor buildx builder container accumulation on the Gitea runner — if more than 2-3 are lingering, clean them up proactively - Consider adding a cleanup step to the CI workflow that prunes old builders after successful builds - The `cache-to: type=registry` directive in the workflow is the trigger — without registry caching this wouldn't happen, but removing it would slow builds significantly