Fix "No space left on device" in GitHub Actions
Fix "No space left on device" in GitHub Actions: see what fills the disk, free space on ubuntu-latest, use /mnt, and get a runner with a bigger disk.
A job fails with one of these, usually in a Docker build, a large npm install, an Android or ML build, or a test that writes a lot of data:
No space left on deviceSystem.IO.IOException: No space left on deviceERROR: failed to solve: ResourceExhausted: ... no space left on deviceYou are running out of disk space. The runner will stop working when the machine runs out of disk space.The runner’s disk is full. On standard GitHub-hosted runners that happens sooner than you’d think: GitHub documents 14 GB of SSD for them, and the root filesystem is shared with the many tools preinstalled in the image. This page shows how to see what’s using the space, then the fixes from the cheapest to the most effective.
See what is using the disk#
Add a step before the failing one (and one with if: always() after it) to see free space and the biggest directories:
- name: Disk usage if: always() run: | df -h sudo du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15 docker system df || truedf -h shows each filesystem. Note which one your job writes to: the workspace ($GITHUB_WORKSPACE, under /home/runner/work), Docker’s data directory (/var/lib/docker), and the temp directory ($RUNNER_TEMP) are all on the root disk by default. On Linux x64 runners a second, larger temporary disk is often mounted at /mnt: if df -h shows one, you can move heavy data there (see below). The exact sizes change with image updates, so read them from your own run.
1. Remove preinstalled tools you don’t use#
The Ubuntu image ships Android SDKs, .NET, Haskell, Swift, CodeQL bundles and several Docker images, which add up to tens of gigabytes. Deleting the ones your job doesn’t need is the quickest fix:
- name: Free disk space uses: jlumbroso/free-disk-space@v2 with: android: true dotnet: true haskell: true large-packages: true # apt packages such as LLVM, browsers, cloud CLIs docker-images: true tool-cache: false # keep setup-python/setup-node caches swap-storage: falseOr by hand, for the biggest directories:
- name: Free disk space run: | sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL sudo docker image prune --all --force df -h /This step takes from a few seconds to a couple of minutes (deleting is I/O too), so keep only the directories that make a difference.
2. Use the second disk#
If /mnt has room, put the heavy data there instead of on /:
- name: Move Docker's data to /mnt run: | sudo systemctl stop docker sudo mkdir -p /mnt/docker echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json sudo systemctl start docker
- name: Build in /mnt run: | sudo mkdir -p /mnt/build && sudo chown "$USER" /mnt/build cmake -S . -B /mnt/build && cmake --build /mnt/buildmaximize-build-space ↗ goes further and merges free space from both disks into one LVM volume mounted on the workspace.
3. Write less#
- Docker builds: use a
.dockerignore, multi-stage builds, anddocker builder prune -afbetween builds in the same job. BuildKit’s own cache counts too: withcache-to: type=gha,mode=maxevery intermediate layer is exported, which takes space during the build. See Docker layer caching. - Caches and artifacts: restoring a cache unpacks it on the disk (a 5 GB compressed cache can take 15 GB). Cache less, or cache per job; see caching dependencies.
- Matrix jobs: split a job that builds everything into a matrix of smaller ones; each gets its own disk.
- Clean as you go: delete build directories and downloaded archives once a step no longer needs them.
4. Get a runner with a bigger disk#
When the job really needs the space, a bigger machine is the fix that doesn’t need maintenance:
- GitHub larger runners come with 150 GB of SSD at 4 vCPUs up to 2,040 GB at 64 vCPUs, on the Team and Enterprise plans, billed per minute.
- Self-hosted runners have whatever disk you give them. On ephemeral cloud runners, size the volume for the job and it’s thrown away afterwards.
- RunsOn runs each job on an EC2 instance in your AWS account and takes the disk size in the job label:
jobs: build: runs-on: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/volume=120gbYou can also pick an instance type with local NVMe storage (a d in the name, such as m6id or m7gd), where RunsOn puts Docker’s data directory on the fast local disk, or mount Docker on RAM with extras=tmpfs on large-memory instances. See the volume label and this tip.
Windows and macOS#
The same message appears as System.IO.IOException: There is not enough space on the disk on Windows. The Windows image is large, and the D: drive usually has more free space than C:: set your build and cache directories there. On macOS runners, df -h and removing unused Xcode versions or simulators (sudo rm -rf /Applications/Xcode_<old>.app, xcrun simctl delete unavailable) free the most space.