Safeguard
Developer Tools•

Why does GitLab run two pipelines, or none, on a merge request?

Branch and merge request pipelines can both start, or neither. Use workflow rules and CI_OPEN_MERGE_REQUESTS so security jobs run once and never skip.

Safeguard Security Team
3 min read

Two pipelines appear when both branch pipelines and merge request pipelines are allowed for the same push. None appear when workflow:rules blocks every type for that event. Fix both by writing explicit workflow rules, using CI_OPEN_MERGE_REQUESTS to skip the branch pipeline while a merge request is open.

Why this is a security problem

Duplicate pipelines waste runner time and can race on deploy jobs. A missing pipeline is worse. If your security scan lives in a job that never starts for merge requests, the merge looks green because nothing ran. GitLab's troubleshooting notes that a merge request can show "Checking pipeline status" indefinitely when "Pipelines must succeed" is on and workflow:rules prevents any pipeline running for it.

How the workflow keyword behaves

GitLab evaluates workflow before jobs. A job cannot run if the workflow blocks its pipeline type. Rules can use when: never to block a type, and a final when: always allows everything else. The documentation warns that if you use both branch and merge request pipelines at once, duplicates might run at the same time.

The standard fix

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH

The first rule runs a merge request pipeline. The second stops the branch pipeline while a merge request is open. The third lets branch pipelines run when no merge request exists. A push to a branch with an open merge request then starts one merge request pipeline.

Values to know

Variable or valueMeaning
merge_request_eventSource value for merge request pipelines
pushBranch and tag pipelines
scheduleScheduled pipelines
trigger and pipelineTriggered pipelines
CI_MERGE_REQUEST_DRAFTLets you skip drafts, GitLab 17.10 and later

GitLab says its list of source values is not complete.

Steps to audit your project

  1. Open a test merge request and count the pipelines. One is the target.
  2. Confirm your scan and test jobs appear in the merge request pipeline, not just the branch pipeline.
  3. Check that required security jobs do not carry rules that exclude merge_request_event.
  4. Remember that rules arriving through include do not count for merge request pipeline matching. Put the matching rule in the main file.
  5. If you skip draft merge requests, make sure the scan still runs before they become ready.
  6. Turn on "Pipelines must succeed" so a missing pipeline is noticed.

Try it yourself

Click through it at your own pace, or open it full screen. Look at what the gate needs in order to run before a merge is allowed.

Our post on pipeline gates that block, warn or log helps decide what each job should do. Safeguard policies and gates are evaluated on connected repositories, so a skipped pipeline job does not skip the check. A free scan is at https://gold.safeguard.sh/scan.

Quick check

Is a green merge request proof the scan ran?

No. Check that the scan job exists in that pipeline.

Do I need both pipeline types?

Often merge request pipelines for review and branch pipelines for the default branch. Just make the rules explicit.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.