"No space left on device" in GitHub Actions: find what fills the disk, free it, or get a bigger one
"No space left on device" on GitHub Actions means the job wrote more than the runner had free, and on GitHub's standard Linux runner that is about 14 GB: a runner-images maintainer wrote that GitHub "guarantee[s] only 14GB of free space for both private & public repos", because the image's preinstalled tools take the rest (one user's listing on ubuntu-latest: 12 GB of Android SDK, 8.5 GB of hosted tool cache, 5.5 GB of GHC). Docker images, a restored cache unpacked on the disk, and build trees fill 14 GB quickly. Fix it in this order: see what fills the disk (df -h, df -i, du, docker system df), write less, delete preinstalled tools the job doesn't use, and if it still doesn't fit, run the job on a bigger disk. GitHub's larger runners have 75 GB and up, on GitHub Team and Enterprise Cloud only.
Skipbox runs your jobs on your account's own machine with 80 GB of disk on S, 160 GB on M and 320 GB on L, for a flat price with unlimited minutes. The caches it keeps between jobs live on that disk, and it trims the oldest of them when the disk gets full, so nothing needs deleting at the start of a job.
How much disk a GitHub runner has
GitHub-hosted runners lists 14 GB of SSD for the standard Linux runner, in private and public repositories. In runner-images discussion #9329, after an image change cut the free space on Ubuntu runners from over 31 GB to over 17 GB, a maintainer answered: "We indeed guarantee only 14GB of free space for both private & public repos." Plan on 14 GB.
The rest of the disk is the image. In issue #10386 ("Free space left: 72 MB"), a user's du on ubuntu-latest showed:
| Directory | Size |
|---|---|
/usr/local/lib/android | 12 GB |
/opt/hostedtoolcache | 8.5 GB (CodeQL alone 5 GB) |
/usr/local/.ghcup | 5.5 GB |
1. See what fills the disk
Add a step after the one that fails, with if: always():
- name: Disk usage
if: always()
run: |
df -h
df -i /
sudo du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15
docker system df || true
df -hshows each filesystem and how full it is. Note which one your job writes to: the workspace, Docker's data under/var/lib/docker, or the temp directory.df -ishows inodes. A disk can run out of inodes (one per file) with bytes still free, and the error is the same.dushows the largest directories.docker system dfshows how much Docker's images, containers, volumes and build cache take.
2. Write less
- Prune Docker between builds.
docker system pruneremoves stopped containers, unused networks, dangling images and unused build cache;-aremoves all unused images, and--volumesanonymous volumes too. - Cache what pays off. A restored cache is unpacked on the runner's disk, so a large cache archive takes more room than its download. Split it per job, or drop what is quick to fetch again.
- Clean build trees a later step doesn't need, before the step that needs the room.
3. Delete the preinstalled tools the job doesn't use
From issue #2875 and #10386:
- name: Free disk space
run: |
sudo rm -rf /usr/local/lib/android /usr/local/.ghcup /opt/hostedtoolcache/CodeQL
sudo rm -rf /usr/share/dotnet /usr/local/share/boost
df -h /
Two costs. Deleting gigabytes takes time on every run, since the next job's VM has them again. And removing $AGENT_TOOLSDIRECTORY (the whole hosted tool cache) frees more but, as the author of #2875 found, breaks the tools steps expect to be there. The free-disk-space action wraps these deletions; its author added the tool-cache option after the thread, saying it "saves an extra 6GB".
4. Run the job on a bigger disk
| Runner | Disk | Who can use it |
|---|---|---|
| GitHub standard Linux runner | 14 GB SSD, about 14 GB free | Everyone |
| GitHub larger runner, 2 to 96 vCPU | 75 GB at 2 vCPU, 150 GB at 4, 300 GB at 8, up to 2,040 GB (larger runners) | GitHub Team and Enterprise Cloud organizations, per minute (about larger runners) |
| Self-hosted runner | What you give it; a runner kept between jobs fills up with images and old workspaces unless something cleans it | Anyone, and you run it |
| Skipbox own machine | 80 GB on S, 160 GB on M, 320 GB on L, trimmed when full | Organizations and personal accounts, flat price |
What Skipbox does with the disk
Each plan comes with your account's own machine, kept between jobs, with the disk of its size:
- The disk is 80 GB on S, 160 GB on M, 320 GB on L.
- What stays on it is your state: Docker's images, layers and build cache,
~/.npm, the pnpm store,~/.cache, the Go, Gradle, Maven and Cargo caches, and the toolssetup-*installed. Whatactions/cachesaves stays next to the machine, up to half the disk. - It doesn't fill up. Nothing is deleted until the disk is more than 85% full after a job. Then it is trimmed back to 75%, least recently used first: dangling images, then Docker's build cache, then whole package caches and kept builds. Only if it is still past 85% is the machine reset.
- The kept caches share the disk with the job. A job that writes tens of gigabytes of its own, such as large images or a big build tree, belongs on M or L.
| Label | Machine | Disk | Plan |
|---|---|---|---|
skipbox | 4 vCPU · 16 GB | 80 GB | S, $39 a month |
skipbox-8x16 | 8 vCPU · 16 GB | 160 GB | M, $79 a month |
skipbox-16x32 | 16 vCPU · 32 GB | 320 GB | L, $149 a month |
Minutes are unlimited. At 20,000 minutes a month on 4 vCPU, GitHub bills $222; Skipbox S is $39.
Moving is one line
jobs:
build:
runs-on: skipbox-8x16 # was ubuntu-latest
steps:
- uses: actions/checkout@v4
# the "Free disk space" step can go
- run: docker build -t app .
skipbox-8x16 runs on an M plan; runs-on: skipbox runs on S and in the trial.
- Sign in to Skipbox with GitHub.
- Install the Skipbox GitHub App and pick the repositories.
- Change
runs-onand push.
Security
- The machine is your account's alone. No other company's jobs run on it.
- After every job, the runner's credentials, processes and containers are wiped, and so are the credential files in the home directory. Clean every job gives each job a fresh machine instead.
- Code from people without write access (such as pull requests from forks) runs on a fresh VM that reads your caches but can't change them.
The details are in how jobs are isolated.
Try it on the job that runs out of disk
The trial is free for 7 days or 3,000 job-minutes, whichever comes first, and takes no card. It runs runs-on: skipbox on S's machine with 80 GB. Move the job there, drop the step that deletes preinstalled tools, and run it.
FAQ
How much disk space does a GitHub Actions runner have?
GitHub's docs list 14 GB of SSD for the standard Linux runner, in private and public repositories alike, and a runner-images maintainer wrote that GitHub guarantees only 14 GB of free space for both. The disk itself is larger, but the runner image's preinstalled tools fill the rest, so plan on 14 GB.
How do I fix No space left on device in GitHub Actions?
First see what filled it: df -h for each filesystem, df -i for inodes, sudo du -xh --max-depth=1 / for the largest directories, and docker system df for Docker's images and build cache. Then write less (prune Docker between builds, cache only what pays off), delete preinstalled tools the job doesn't use (the Android SDK, GHC, CodeQL, .NET), and if the job still needs more, run it on a runner with a bigger disk.
What can I delete from ubuntu-latest to free disk space?
Tools the job doesn't use. Users in GitHub's runner-images issues remove /usr/local/lib/android (12 GB in one user's listing), /usr/local/.ghcup, /opt/hostedtoolcache/CodeQL, /usr/share/dotnet and /usr/local/share/boost. Removing $AGENT_TOOLSDIRECTORY frees the hosted tool cache too, but breaks setup steps that expect their tools there. Deleting gigabytes takes time on every run.
Do GitHub's larger runners have more disk?
Yes: 75 GB at 2 vCPU, 150 GB at 4, 300 GB at 8, up to 2,040 GB at 64 and 96 vCPU. They are only for organizations on GitHub Team or GitHub Enterprise Cloud, billed per minute.
How much disk does Skipbox give a job?
Your account's own machine has 80 GB on S, 160 GB on M and 320 GB on L. The caches kept between jobs share that disk: after a job that leaves it more than 85% full, it is trimmed back to 75%, least recently used first, so it doesn't fill up the way a self-hosted runner's disk does. A job that writes tens of gigabytes of its own belongs on M or L.
How much does it cost to try?
Nothing. The trial is 7 days or 3,000 job-minutes, whichever comes first, with no card, on S's machine. Move the job that runs out of disk to runs-on: skipbox and drop the steps that delete preinstalled tools.
Updated November 13, 2026