Fail Fast

Fail-fast is the matrix strategy setting that cancels the remaining matrix jobs when one leg fails. What it defaults to, and when to switch it off.

Fail-fast is the matrix strategy setting that cancels the remaining jobs in a matrix as soon as one of its jobs fails. It lives under jobs.<job_id>.strategy in a workflow file, it defaults to true, and while it is on, the first failing combination ends the other combinations before they reach a conclusion.

The setting decides how much a single run tells you. Cancelling early stops spending machine time on combinations that may be about to fail for the same reason, while letting every leg finish produces the complete failure list from one run.

Definition

fail-fast is a boolean under a job's strategy key, alongside matrix and max-parallel. GitHub documents the default as true and describes the behavior as cancelling all in-progress and queued jobs in the matrix when any job in that matrix fails (GitHub workflow syntax, checked on 2026-08-13).

Three details narrow what the word covers.

The scope is one matrix. A workflow with three matrix jobs has three independent fail-fast decisions, and a failure in one job's matrix does not cancel the legs of another job's matrix. Jobs that list the failing job in needs are skipped for the usual dependency reason instead.

The conclusion is cancelled rather than failure. A leg that was cancelled midway reports no test result, so the run view shows one red leg and several grey ones, and the grey ones are unknown rather than passing.

The trigger is a failed job, so the setting interacts with continue-on-error. A leg marked continue-on-error: true that fails does not fail the workflow run, which is the documented way to carry an experimental combination inside a matrix that otherwise stops on failure.

KeyWhere it sitsWhat it decides
strategy.fail-fastUnder jobs.<job_id>.strategyWhether the first failing leg cancels the rest of the matrix. Default true.
strategy.max-parallelUnder jobs.<job_id>.strategyHow many legs of the matrix run at the same time.
jobs.<job_id>.continue-on-errorOn the jobWhether a failing job marks the workflow run as failed.
steps[*].continue-on-errorOn a stepWhether a failing step marks its job as failed.

A matrix can expand to at most 256 jobs per workflow run, so the number of legs a single failure can cancel is bounded by that limit (GitHub Actions limits, checked on 2026-08-13).

What each setting costs

With fail-fast on its default, a run stops at the first failure and the minutes already spent on the cancelled legs are still spent. If two combinations are broken, the second one appears only after the first is fixed, so the debugging loop is one run per failure.

With fail-fast: false, every combination runs to completion and bills its own minutes, and one run produces the whole failure list. The trade is machine time against the number of round trips it takes to see the true state of the matrix.

Example

This workflow tests six combinations, three operating systems against two Node versions, with fail-fast: false so that every combination reports.

name: test
on:
  pull_request:

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [20, 22]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test -- --reporter=junit --outputFile=reports/junit.xml
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: junit-${{ matrix.os }}-node${{ matrix.node }}
          path: reports/

Two lines in that file exist because of the setting. fail-fast: false keeps the five healthy legs running when one breaks. if: always() on the upload step keeps the report from a leg that was cancelled or failed, since a step guarded only by the default success condition is skipped the moment the job stops being successful. The artifact name includes both matrix values because actions/upload-artifact@v4 rejects two uploads under the same name in one run, and a matrix would otherwise send six uploads to one name.

Now take a run where the Windows leg on Node 20 fails two minutes in and the macOS leg on Node 22 fails at four minutes, while the other four legs need six minutes each to pass.

LegWith the default fail-fast: trueWith fail-fast: false
ubuntu-latest, Node 20Cancelled at 2 minutes, result unknownPasses at 6 minutes
ubuntu-latest, Node 22Cancelled at 2 minutes, result unknownPasses at 6 minutes
macos-latest, Node 20Cancelled at 2 minutes, result unknownPasses at 6 minutes
macos-latest, Node 22Cancelled at 2 minutes, result unknownFails at 4 minutes, report uploaded
windows-latest, Node 20Fails at 2 minutes, report uploadedFails at 2 minutes, report uploaded
windows-latest, Node 22Cancelled at 2 minutes, result unknownPasses at 6 minutes
Total job minutes1230
Failures visible after one run1 of 22 of 2

The default run is cheaper by 18 job minutes and leaves one of the two real failures undiscovered. A developer fixes the Windows failure, pushes, and meets the macOS failure on the next run, so the wall clock cost of the second setting is measured against an extra full pipeline round trip rather than against zero.

That trade shifts with what the matrix is for. A matrix that exists to prove one artifact builds everywhere can stop at the first failure, because the artifact is already unshippable. A matrix that shards a test suite has legs that fail for unrelated reasons, and cancelling the siblings throws away results the run had already produced.

FAQ

What is fail-fast in a GitHub Actions matrix?

It is the key under a job's strategy block that decides what happens to the rest of a matrix when one combination fails. With fail-fast set to true, the default, GitHub cancels every in-progress and queued job in that matrix as soon as the first one fails. With it set to false, each combination runs to its own conclusion and the run reports all of them.

Does fail-fast default to true or false?

True. A matrix with no fail-fast key behaves as if fail-fast were set to true, so the first failing combination cancels its siblings. Writing fail-fast false is the only way to keep every leg running.

When should a matrix set fail-fast to false?

When the value of the run is the full list of failures rather than the earliest one. Cross platform matrices, version compatibility matrices, and sharded test suites all fit, because a single leg cancelling the others hides how many combinations are broken and forces one run per fix.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.