Syft SBOM No Space Left On GitHub Actions
When a large Docker image builds, pushes, and signs successfully, then Syft fails while writing sbom.spdx.json, the SBOM step is often the first step that needs extra runner scratch after the image layers already consumed the small hosted-runner root disk.
CI cleanup request
Get the exact runner cleanup step.
Leave your email now; the scan summary or failing job link can follow after the first reply. We send the $29 Deep Cleanup step only if the runner still needs review.
First Response Runbook
- Log disk before build, after push/sign, and immediately before Syft.
- Measure Docker and BuildKit separately;
docker system dfcan hide build-cache detail. - Keep published image digests, cosign signatures, and failure logs; those are evidence, not cleanup targets.
- Prefer freeing local build cache before Syft over deleting named volumes or workspace state.
- If possible, generate the SBOM from the remote digest or pipe output directly into attestation so the runner does not need a large on-disk
sbom.spdx.json.
echo "before sbom"
df -h / "$GITHUB_WORKSPACE" /tmp 2>/dev/null || true
docker system df || true
docker buildx du 2>/dev/null || true
du -sh "$GITHUB_WORKSPACE" /tmp "$HOME/.cache" 2>/dev/null || true
# If the image is already pushed and signed, free local build cache before Syft.
docker builder prune -af 2>/dev/null || true
docker image prune -af 2>/dev/null || true
echo "after local cache prune"
df -h / "$GITHUB_WORKSPACE" /tmp 2>/dev/null || true
docker system df || true
Safer Fix Options
- Best first check: run Syft after local image/build-cache cleanup, while preserving the remote digest and logs.
- Lower local disk pressure: run Syft against the pushed image digest with a reduced scope when acceptable for the policy.
- Avoid a second large file: pipe Syft JSON/SPDX output into the attestation command instead of writing a workspace file first.
- Budget rule: before the SBOM step, reserve enough free disk for Syft scratch plus the final SBOM file.
Copy-ready issue reply
Use this when Syft fails after image publish.
This keeps the thread focused on the SBOM peak instead of a broad runner cleanup script.
I would treat the Syft step as the peak-storage point after the large image has already occupied the runner, not as proof that the image publish itself failed.
Useful evidence right before Syft:
df -h / "$GITHUB_WORKSPACE" /tmp 2>/dev/null || true
docker system df || true
docker buildx du 2>/dev/null || true
du -sh "$GITHUB_WORKSPACE" /tmp "$HOME/.cache" 2>/dev/null || true
If the image is already pushed and signed, the safer order is:
1. keep the pushed digest, cosign signature, and job logs
2. prune local build/image cache only if no later step needs local layers
3. rerun Syft, or generate from the remote digest / pipe output into attest so `sbom.spdx.json` does not create another large workspace file
I would avoid deleting Docker volumes or workspace data as the first move; the likely disposable bucket is local build cache after the image is already published.
Deep Cleanup
Need a cleanup order for this runner?
Submit the form first; the failing job link can follow. We check whether free guidance is enough before asking for the $29 Deep Cleanup.