Skip to content

How to Fix GitLab CI Artifact Upload Errors

DodaTech 2 min read

In this tutorial, you'll learn about How to Fix GitLab CI Artifact Upload Errors. We cover key concepts, practical examples, and best practices.

The Problem

Your GitLab CI job fails with Uploading artifacts to coordinator... too large or Uploading artifacts to coordinator... failed. GitLab enforces a default artifact size limit of 100MB per job on most instances. When the total size of the files in your artifacts:paths exceeds this limit, or when the runner disk runs out of space, the upload fails. Incorrect expire_in settings can also cause artifact storage to grow unbounded.

Quick Fix

1. Reduce artifact size by archiving only what is needed

In .gitlab-ci.yml:

build:
  stage: build
  artifacts:
    paths:
      - dist/
      - build/libs/*.jar
    exclude:
      - node_modules/**
      - .cache/**
      - "**/*.map"
    expire_in: 1 week

2. Compress artifacts before uploading

build:
  stage: build
  before_script:
    - npm ci
  script:
    - npm run build
    - tar -czf dist.tar.gz dist/
  artifacts:
    paths:
      - dist.tar.gz
    expire_in: 1 week

3. Increase the artifact size limit in GitLab admin

If you are a GitLab admin, increase the limit:

sudo gitlab-rails console
> Plan.default.actual_limits.update!(ci_max_artifact_size: 500)

For Omnibus installs, edit /etc/gitlab/gitlab.rb:

gitlab_rails['artifacts_max_size'] = 500

Then reconfigure:

sudo gitlab-ctl reconfigure

4. Debug disk space on the runner

df -h
du -sh /builds/$CI_PROJECT_PATH/

Expected output:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       100G   45G   55G  46% /

If the runner disk is full, clean up old builds:

docker system prune -af

5. Set artifact expiry correctly

build:
  artifacts:
    paths:
      - dist/
    expire_in: 1 day
    when: always

Use when: always to upload artifacts even when the job fails — useful for debugging:

test:
  stage: test
  artifacts:
    paths:
      - test-results/
    when: always
    expire_in: 1 week

6. Use dependency to download only needed artifacts

deploy:
  stage: deploy
  dependencies:
    - build
  script:
    - ls dist/
    - scp dist/* user@server:/var/www/html/

7. Run a cleanup job to remove old artifacts regularly

cleanup:
  stage: cleanup
  script:
    - echo "Artifacts are automatically cleaned by expire_in"
  only:
    - schedules

8. Use parallel jobs with independent artifact paths

build:linux:
  stage: build
  artifacts:
    paths:
      - build/linux/
  script:
    - mkdir -p build/linux && cp binary build/linux/

build:macos:
  stage: build
  artifacts:
    paths:
      - build/macos/
  script:
    - mkdir -p build/macos && cp binary build/macos/

9. Use the GitLab API to download the latest artifact

curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/main/download?job=build"

This is useful for external tools that need to fetch build outputs.

Prevention

  • Set expire_in on every artifact to prevent unbounded storage growth
  • Use exclude patterns to skip large generated directories like node_modules
  • Monitor artifact storage usage via GitLab admin area (Settings → Monitoring → Usage)
  • Use dependencies in downstream jobs to pull only the artifacts you actually need
  • Configure runner cleanup with docker system prune -af in a cron job for Docker-based runners

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro