GitLab CI allow_failure: let a job fail without failing the pipeline

By Melih Toksari, developer of MergeBell · Updated · 3 min read

Short answer

With allow_failure: true, a job can fail without failing the pipeline: the job shows an orange warning, later stages still run, and the pipeline succeeds with a Warning badge. A merge request that needs a successful pipeline can still merge. It is true by default for a manual job added with when: manual on the job, and false for one added with when: manual inside rules, which then blocks the pipeline until someone runs it. allow_failure:exit_codes limits it to chosen exit codes, and rules:allow_failure sets it for one rule.

A flaky end-to-end suite, a linter you’re still rolling out, a scan that shouldn’t hold up a hotfix: some jobs are worth running without letting them fail the pipeline. That’s what allow_failure is for. Here is what it does in GitLab CI/CD in 2026, its defaults, and where it surprises people.

What allow_failure does

lint:
  stage: test
  script: npm run lint
  allow_failure: true

When lint fails:

  • The job shows an orange warning, not a red cross.
  • Later stages still start. Jobs with when: on_success, the default, treat it as successful, and so do jobs that list it in needs.
  • The pipeline succeeds. GitLab marks it with an orange Warning badge, the merge request widget says it passed with warnings, and the API reports success.
  • Jobs with when: on_failure don’t start, because as far as the pipeline is concerned nothing failed.

Without it, a failed job stops the later stages and fails the pipeline. false is the default for ordinary jobs.

The defaults for manual jobs

How the job is made manual Default What the pipeline does
when: manual on the job allow_failure: true Carries on without it: the job is optional
when: manual inside rules allow_failure: false Stops at the job’s stage, blocked, until someone runs it and it succeeds

So a pipeline that shows blocked has a manual job waiting. To make it optional, add allow_failure: true to the rule:

deploy_review:
  script: ./deploy.sh review
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
      allow_failure: true

A job that needs an optional manual job is skipped while nobody has run it; if someone runs the manual job later, GitLab resets the skipped job and runs it afterwards. More on running and unblocking manual jobs in how to run a manual job in GitLab CI/CD.

Only for some exit codes

allow_failure:exit_codes lets the job fail with the exit codes you list, and fails it as usual with any other:

e2e:
  script: ./run-e2e.sh
  allow_failure:
    exit_codes: 42

Have the script exit with 42 when it hits the known flaky case, and any other failure still stops the pipeline. Choose the codes with care: 137, which GitLab’s own example lists, is a job killed by the system, often for running out of memory.

Per rule

rules:allow_failure applies when that rule adds the job, and overrides the job’s own allow_failure:

security_scan:
  script: ./scan.sh
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      allow_failure: true

Here the scan has to pass on the default branch, and only warns in merge request pipelines.

What it means for merging

A pipeline that passed with warnings is a successful pipeline. Pipelines must succeed lets the merge request through, and auto-merge goes ahead too. That’s the point of allow_failure, and its risk: the failure stops nobody, so somebody has to read the warning. When it’s real, fix it or retry the job. A blocked manual job is the opposite problem, and why can’t I merge my GitLab merge request? covers it with the other blockers.

On your phone

In MergeBell, a failed job that’s allowed to fail is marked allowed to fail, and its stage still shows as passed, so an allowed failure doesn’t make the pipeline look broken. Live job logs, retry, cancel and manual jobs are on the free tier, on iPhone and Android.

Frequently asked questions

What does allow_failure do in GitLab CI?

It lets a job fail without failing the pipeline. The failed job shows an orange warning, jobs in later stages still start, and the pipeline's status is success, which GitLab marks with an orange Warning badge.

Can a merge request merge if an allow_failure job failed?

Yes. The pipeline counts as successful, so Pipelines must succeed and auto-merge let the merge request through even though that job failed.

Why is my manual job blocking the pipeline?

A manual job added with when: manual inside rules defaults to allow_failure: false, so the pipeline stops at its stage until someone runs it and it succeeds. Add allow_failure: true to that rule to make the job optional. A manual job added with when: manual on the job itself is optional by default.

How do I allow a job to fail only for certain exit codes?

Use allow_failure:exit_codes with one exit code or a list of them, such as exit_codes: 42 for a code your script returns on a known flaky failure. The job may fail with those codes; any other exit code fails it as usual.

Does a job that needs an allow_failure job still run if that job fails?

Yes. GitLab treats the failed job as successful when it decides what runs next, so jobs that list it in needs, and jobs in later stages, still start. Jobs with when: on_failure don't, because as far as the pipeline is concerned nothing failed.

Sources

Checked against these pages on 29 October 2026. GitLab changes quickly — if something here no longer matches, tell us and we will fix it.

Do this from your phone with MergeBell

Free for the whole review loop: the To-Do inbox, diffs and line comments, approve and merge, pipelines with retry, and push alerts for your To-Dos. Works with gitlab.com and self-managed GitLab 16.0+.

Get MergeBell for iPhoneGet MergeBell for Android

On the App Store for iOS 26 or later and on Google Play for Android 12 or later. An independent app, not affiliated with GitLab Inc.