GitLab CI/CD Configuration Validator

Paste a .gitlab-ci.yml to check its structure without pushing and without a GitLab token. Every finding names the line, the job and what GitLab expects.

Loading tool…

About the GitLab CI Validator

In a .gitlab-ci.yml, a handful of top-level keys are global keywords — stages, variables, default, include, workflow — and every other top-level key is a job. That is why a typo such as variabels: is read as a job without a script. The validator separates the two, treats names that start with a dot as hidden jobs (templates), and checks that every visible job has script, trigger or run, either directly or through extends. A command that contains a colon and a space, such as echo "status: ok" written without outer quotes, is parsed by YAML as a mapping, which is the most common reason for script config should be a string or a nested array of strings.

Relations between jobs are checked: stage must be listed in stages (the defaults are .pre, build, test, deploy, .post); needs, dependencies and extends must name jobs that exist; a job cannot need a job of a later stage; and extends and needs must not form a cycle. only / except cannot be combined with rules in the same job. Values are checked as well: when (on_success, on_failure, always, manual, delayed, never), retry from 0 to 2, parallel from 1 to 200 or a matrix, artifacts:paths as a list, and start_in only with when: delayed.

The check works offline, which is its limit: files named in include are not fetched, so a job, template or stage that is missing from this file is reported as a warning instead of an error when the file has includes. GitLab's own CI Lint (the API or the pipeline editor) resolves includes and knows the features of your instance and version; use it as the final check. Anchors, merge keys (<<) and !reference tags are understood. Duplicate keys are reported as warnings, because GitLab keeps the last definition without telling you.

How to use it

  1. Paste your .gitlab-ci.yml or open the file.
  2. Read the verdict above the editors: stages in order with their jobs, templates and includes.
  3. Go through the findings, sorted by line. Errors prevent GitLab from creating the pipeline.
  4. Fix the file and watch the list update. “Sample with errors” shows typical mistakes.

Frequently asked questions

How is this different from GitLab's CI Lint?
GitLab's CI Lint runs on the server with your project: it merges include files, expands variables and knows which keywords your version supports. This validator needs no account and no network, works on the single file you paste, and explains common mistakes in more detail. Use it while editing and CI Lint before merging.
Why can I not combine only and rules?
They are two generations of the same feature. rules replaces only and except and is evaluated differently, so GitLab rejects a job that uses both. Rewrite only: [main] as a rule: - if: $CI_COMMIT_BRANCH == "main".
What is a hidden job?
A job whose name starts with a dot, such as .deploy-template. GitLab does not run it, so it does not need a script. It is used as a template that other jobs pull in with extends, with a YAML anchor or with !reference.
Which stages exist when I do not define stages?
.pre, build, test, deploy and .post, in that order. A job without stage belongs to test. When you define stages yourself, only your stages plus .pre and .post exist.

Related tools