🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

GitHub Actions Artifact Upload Failing — Size Limit & Permissions Fix

Your GitHub Actions artifact upload is failing with 'upload artifact failed' or size limit errors. Here are the exact causes and fixes for the most common artifact upload failures.

DevOpsBoysJun 14, 20264 min read
Share:Tweet

Artifact upload failures in GitHub Actions are frustrating because the error messages are often vague. "Upload artifact failed" tells you nothing. Here are the actual causes and how to fix each one.

The Most Common Error Messages

Error: Artifact upload failed with error: RequestError: connect ETIMEDOUT
Error: ENOSPC: no space left on device
Error: Artifact upload failed: 413 Request Entity Too Large  
Warning: No files were found with the provided path

Each one has a different fix.

Fix 1: File Path Not Found (Most Common)

yaml
# BROKEN — path doesn't match where files actually are
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/          # ← files might be in ./dist/ or build/

The action silently succeeds but uploads nothing, or fails with "No files were found."

Diagnose it first:

yaml
- name: Debug — list files before upload
  run: |
    echo "Current directory: $(pwd)"
    find . -name "*.zip" -o -name "*.tar.gz" | head -20
    ls -la dist/ 2>/dev/null || echo "dist/ does not exist"

Fix — use explicit paths and verify:

yaml
- name: Build
  run: npm run build   # outputs to ./dist
 
- name: Upload artifact
  uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: |
      dist/
      !dist/**/*.map   # exclude source maps to reduce size
    if-no-files-found: error   # fail loudly instead of silently

Fix 2: Artifact Too Large (413 Error)

GitHub Actions has artifact size limits:

  • Free/Pro/Team: 500 MB per artifact
  • Enterprise: 500 MB per artifact (configurable)
  • Total storage per repo: 1 GB (free), more on paid plans
yaml
# Compress before uploading
- name: Compress artifacts
  run: |
    tar -czf artifacts.tar.gz dist/ logs/ reports/
    ls -lh artifacts.tar.gz   # check compressed size
 
- name: Upload compressed artifact
  uses: actions/upload-artifact@v4
  with:
    name: build-artifacts
    path: artifacts.tar.gz
    compression-level: 9   # max compression (0-9)

If you're uploading test reports or logs, filter aggressively:

yaml
- name: Upload only test failures
  uses: actions/upload-artifact@v4
  with:
    name: test-results
    path: |
      test-results/**/*.xml
      !test-results/**/passed/**   # exclude passing test files
    retention-days: 7              # don't keep forever

Fix 3: ETIMEDOUT — Network Timeout

This happens when the runner can't reach GitHub's artifact storage endpoint. Common in self-hosted runners on restricted networks.

yaml
# Add retry logic
- name: Upload artifact with retry
  uses: nick-fields/retry@v3
  with:
    timeout_minutes: 10
    max_attempts: 3
    command: |
      gh run upload-artifact --name build-output --path dist/

Or use the built-in retry on the action:

yaml
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/
  # GitHub-hosted runners rarely time out — this is mostly self-hosted runner issue
  # Check your runner's outbound access to *.actions.githubusercontent.com

For self-hosted runners, verify network access:

bash
# On the runner machine
curl -I https://pipelines.actions.githubusercontent.com
# Should return 200 or 302, not timeout

Fix 4: Disk Space (ENOSPC)

Self-hosted runners or runners with large builds run out of disk during artifact preparation.

yaml
- name: Free disk space before build
  run: |
    df -h   # check current disk usage
    docker system prune -af   # clean docker if available
    rm -rf /tmp/*
    df -h   # check again
 
- name: Build
  run: make build
 
- name: Upload artifact
  uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/

For GitHub-hosted runners, the ubuntu-latest runner has ~14GB free. If you're hitting ENOSPC on GitHub-hosted runners, your build is generating too many intermediate files:

yaml
- name: Clean build intermediates before upload
  run: |
    # Keep only final outputs, delete intermediates
    find build/ -name "*.o" -delete   # C/C++ object files
    find build/ -name "*.tmp" -delete
    du -sh dist/   # check what you're actually uploading

Fix 5: Wrong Permissions on Artifact Files

Error: EACCES: permission denied, open '/home/runner/work/repo/dist/output.bin'
yaml
- name: Fix permissions before upload
  run: chmod -R 644 dist/
 
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/

The Complete Working Pattern

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
 
    - name: Build
      run: npm ci && npm run build
 
    - name: Verify output exists
      run: |
        test -d dist/ || (echo "dist/ not found" && exit 1)
        echo "Artifact size: $(du -sh dist/)"
 
    - name: Upload build artifact
      uses: actions/upload-artifact@v4
      with:
        name: build-${{ github.sha }}
        path: dist/
        retention-days: 30
        if-no-files-found: error
        compression-level: 6
 
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
    - name: Download artifact
      uses: actions/download-artifact@v4
      with:
        name: build-${{ github.sha }}
        path: dist/
 
    - name: Deploy
      run: ./deploy.sh

Quick Diagnosis Checklist

  1. Add if-no-files-found: error — never let silent failures through
  2. Print the path before upload — ls -la or find
  3. Check artifact size — du -sh path/
  4. On self-hosted runners — check outbound network and disk space
  5. Use actions/upload-artifact@v4 — v1/v2 are deprecated and have more bugs

Set up CI/CD from scratch: GitHub Actions CI/CD Tutorial

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments