- Verify syntax
- Verify variables
- GitLab CI/CD documentation
Common CI/CD issues
- Jobs or pipelines don’t run when expected
- A job runs unexpectedly
- “fatal: reference is not a tree” error
- Merge request pipeline messages
- Merge request status messages
- Pipeline warnings
- How to get help
GitLab provides several tools to help make troubleshooting your pipelines easier.
This guide also lists common issues and possible solutions.
An early source of problems can be incorrect syntax. The pipeline shows a
badge and does not start running if any syntax or formatting problems are found.
The GitLab Web IDE offers advanced authoring tools,
including syntax highlighting for the
.gitlab-ci.yml, and is the recommended editing
experience (rather than the single file editor). It offers code completion suggestions
that ensure you are only using accepted keywords.
If you prefer to use another editor, you can use a schema like the Schemastore
with your editor of choice.
The CI Lint tool is a simple way to ensure the syntax of a CI/CD configuration
file is correct. Paste in full
gitlab-ci.yml files or individual jobs configuration,
to verify the basic syntax.
.gitlab-ci.yml file is present in a project, you can also use the CI Lint
tool to simulate the creation of a full pipeline.
It does deeper verification of the configuration syntax.
A key part of troubleshooting CI/CD is to verify which variables are present in a pipeline, and what their values are. A lot of pipeline configuration is dependent on variables, and verifying them is one of the fastest ways to find the source of a problem.
Export the full list of variables available in each problematic job. Check if the variables you expect are present, and check if their values are what you expect.
gitlab-ci.yml reference contains a full list of
every keyword you may need to use to configure your pipelines.
Some pipeline types have their own detailed usage guides that you should read if you are using that type:
- Multi-project pipelines: Have your pipeline trigger a pipeline in a different project.
- Parent/child pipelines: Have your main pipeline trigger and run separate pipelines in the same project. You can also dynamically generate the child pipeline’s configuration at runtime.
- Pipelines for Merge Requests: Run a pipeline in the context of a merge request.
There are troubleshooting guides available for some CI/CD features and related topics:
A lot of common pipeline issues can be fixed by analyzing the behavior of the
only/except configuration. You shouldn’t use these two configurations in the same
pipeline, as they behave differently. It’s hard to predict how a pipeline runs with
this mixed behavior.
only/except keywords are what determine whether or not a job is
added to a pipeline. If a pipeline runs, but a job is not added to the pipeline,
it’s usually due to
only/except configuration issues.
If a pipeline does not seem to run at all, with no error message, it may also be
only/except configuration, or the
workflow: rules keyword.
If you are converting from
only/except to the
rules keyword, you should check
rules configuration details carefully. The behavior
rules is different and can cause unexpected behavior when migrating
between the two.
if clauses for
can be very helpful for examples of how to write rules that behave the way you expect.
Two pipelines can run when pushing a commit to a branch that has an open merge request associated with it. Usually one pipeline is a merge request pipeline, and the other is a branch pipeline.
This is usually caused by the
rules configuration, and there are several ways to
prevent duplicate pipelines.
Before a pipeline can run, GitLab evaluates all the jobs in the configuration and tries to add them to all available pipeline types. A pipeline does not run if no jobs are added to it at the end of the evaluation.
If a pipeline did not run, it’s likely that all the jobs had
blocked them from being added to the pipeline.
If the wrong pipeline type ran, then the
only/except configuration should
be checked to make sure the jobs are added to the correct pipeline type. For
example, if a merge request pipeline did not run, the jobs may have been added to
a branch pipeline instead.
It’s also possible that your
workflow: rules configuration
blocked the pipeline, or allowed the wrong pipeline type.
A common reason a job is added to a pipeline unexpectedly is because the
keyword always evaluates to true in certain cases. For example,
changes is always
true in certain pipeline types, including scheduled pipelines and pipelines for tags.
changes keyword is used in combination with
rules). It’s recommended to use
only/except configuration that ensures the job is only added to branch
pipelines or merge request pipelines.
Introduced in GitLab 12.4.
Previously, you’d have encountered unexpected pipeline failures when you force-pushed a branch to its remote repository. To illustrate the problem, suppose you’ve had the current workflow:
- A user creates a feature branch named
exampleand pushes it to a remote repository.
- A new pipeline starts running on the
- A user rebases the
examplebranch on the latest
masterbranch and force-pushes it to its remote repository.
- A new pipeline starts running on the
examplebranch again, however, the previous pipeline (2) fails because of
fatal: reference is not a tree:error.
This is because the previous pipeline cannot find a checkout-SHA (which is associated with the pipeline record)
example branch that the commit history has already been overwritten by the force-push.
Similarly, Pipelines for merged results
might have failed intermittently due to the same reason.
As of GitLab 12.4, we’ve improved this behavior by persisting pipeline refs exclusively. To illustrate its life cycle:
- A pipeline is created on a feature branch named
- A persistent pipeline ref is created at
refs/pipelines/<pipeline-id>, which retains the checkout-SHA of the associated pipeline record. This persistent ref stays intact during the pipeline execution, even if the commit history of the
examplebranch has been overwritten by force-push.
- The runner fetches the persistent pipeline ref and gets source code from the checkout-SHA.
- When the pipeline finishes, its persistent ref is cleaned up in a background process.
The merge request pipeline widget shows information about the pipeline status in a merge request. It’s displayed above the ability to merge status widget.
This message is shown when the merge request has no pipeline associated with the latest commit yet. This might be because:
- GitLab hasn’t finished creating the pipeline yet.
- You are using an external CI service and GitLab hasn’t heard back from the service yet.
- You are not using CI/CD pipelines in your project.
- The latest pipeline was deleted (this is a known issue).
After the pipeline is created, the message updates with the pipeline status.
The merge request status widget shows the Merge button and whether or not a merge request is ready to merge. If the merge request can’t be merged, the reason for this is displayed.
If the pipeline is still running, the Merge button is replaced with the Merge when pipeline succeeds button.
If Merge Trains are enabled, the button is either Add to merge train or Add to merge train when pipeline succeeds.
This message is shown if the Pipelines must succeed setting is enabled in the project and a pipeline has not yet run successfully. This also applies if the pipeline has not been created yet, or if you are waiting for an external CI service. If you don’t use pipelines for your project, then you should disable Pipelines must succeed so you can accept merge requests.
Pipeline configuration warnings are shown when you:
When you use
rules with a
when: clause without an
clause, multiple pipelines may run. Usually this occurs when you push a commit to
a branch that has an open merge request associated with it.
If you are unable to resolve pipeline issues, you can get help from: