Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for GitLab CI/CD By James Joyner IV · · 8 min read

GitLab CI Error Guide: 'parallel should be an integer' — Fix Parallel Config

Quick answer

Fix 'parallel config should be an integer between 1 and 200' in GitLab CI: set a valid count, quote matrix values, and split parallel from parallel:matrix.

  • #gitlab
  • #ci-cd
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

GitLab rejects the pipeline configuration when a job’s parallel: keyword has a value outside the allowed range or of the wrong type. The parser fails before any job runs:

Found errors in your .gitlab-ci.yml:
  jobs:test:parallel config should be an integer between 1 and 200

The parallel:matrix: variant reports a related shape error when the matrix isn’t a proper list of variable maps:

jobs:test:parallel:matrix config should be an array of hashes

Either way the config is invalid and no pipeline is created until the value is corrected.

Symptoms

  • The pipeline fails at parse time citing parallel and the 1–200 range.
  • A parallel: value came from a variable that expanded to a non-integer or empty string.
  • Someone set parallel: 0 or a very large number expecting “as many as possible.”
  • A parallel:matrix: block is written as a map instead of a list, or matrix values aren’t quoted strings.
  • CI Lint flags the job while the surrounding YAML looks correct.

Common Root Causes

  • Out-of-range valueparallel: 0, a negative number, or a value above 200.
  • Non-integer / variable valueparallel: "$SHARDS" where the variable is empty or non-numeric (parallel: does not interpolate variables the way script: does).
  • Quoted where a number is required — some contexts accept parallel: "5", but a malformed/empty quoted value fails.
  • Confusing parallel with parallel:matrix — using a bare integer when you meant a matrix, or vice versa.
  • Malformed matrix shapeparallel:matrix: written as a single mapping rather than a list (-) of variable maps.
  • Unquoted matrix values that YAML mistypes — a version like 3.10 parsed as a float 3.1, or on/no parsed as booleans.

Diagnostic Workflow

Validate the config and confirm the exact keyword shape with CI Lint:

lint:
  image: curlimages/curl:latest
  script:
    - |
      curl --silent --header "PRIVATE-TOKEN: $LINT_TOKEN" \
        "https://$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/ci/lint" \
        --data-urlencode "content=$(cat .gitlab-ci.yml)"

For a simple sharded job, use a literal integer in range — not a variable:

# Valid: literal integer, 1..200 — creates N parallel job instances
test:
  parallel: 5
  script:
    - ./run-shard.sh "$CI_NODE_INDEX" "$CI_NODE_TOTAL"

For a matrix, write a LIST of variable maps and quote values so YAML doesn’t retype them:

# Valid parallel:matrix — a sequence (-) of hashes, all values quoted
test:
  parallel:
    matrix:
      - PYTHON: ["3.10", "3.11", "3.12"]   # quoted so 3.10 stays a string
        DB: ["postgres", "mysql"]
  script:
    - ./test.sh

Example Root Cause Analysis

A team wanted the shard count configurable per environment, so they wired it through a variable:

variables:
  SHARDS: ""            # default left empty, set per-schedule

test:
  parallel: "$SHARDS"   # <-- parallel does not interpolate this
  script:
    - ./run-shard.sh

The pipeline failed with jobs:test:parallel config should be an integer between 1 and 200. The parallel: keyword is resolved at config-parse time and does not expand CI variables the way script lines do — "$SHARDS" was treated as a literal, non-integer string (and was empty besides). The fix was to use a literal integer, and where per-context variation was genuinely needed, to select among predefined jobs with rules: rather than trying to interpolate the count:

test:
  parallel: 8          # literal integer in range
  script:
    - ./run-shard.sh "$CI_NODE_INDEX" "$CI_NODE_TOTAL"

For the rare case that truly needed a variable shard count, they generated the job via a dynamic child pipeline, where the count is computed and written into the generated YAML as a literal before it is triggered.

Prevention Best Practices

  • Use a literal integer between 1 and 200 for parallel:; don’t feed it a CI variable, which it won’t interpolate at parse time.
  • For version/OS matrices, use parallel:matrix: as a sequence of variable maps, not a single mapping.
  • Quote matrix values ("3.10", "on", "no") so YAML doesn’t retype them as floats or booleans.
  • Run CI Lint in a pre-merge job to catch range/shape errors before the default branch.
  • When you genuinely need a computed count, generate it into a dynamic child pipeline as a literal, rather than interpolating parallel:.
  • Keep parallel (simple sharding) and parallel:matrix (dimension expansion) conceptually separate and pick the right one deliberately.

Quick Command Reference

# Validate the config locally
glab ci lint .gitlab-ci.yml

# CI Lint via API
curl --header "PRIVATE-TOKEN: $TOKEN" \
  "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/ci/lint" \
  --data-urlencode "content=$(cat .gitlab-ci.yml)"

# Confirm a matrix value stays a string in YAML (float trap)
python -c "import yaml,sys; print(yaml.safe_load('v: 3.10'))"   # -> {'v': 3.1} if unquoted!
python -c "import yaml,sys; print(yaml.safe_load('v: \"3.10\"'))" # -> {'v': '3.10'}

Conclusion

parallel config should be an integer between 1 and 200 means the parallel: value is out of range, the wrong type, or an un-interpolated variable — GitLab resolves this keyword at parse time and won’t expand CI variables into it. Use a literal integer in range, express version/OS fan-out with a properly-shaped parallel:matrix: list of quoted variable maps, and validate with CI Lint. When you truly need a computed shard count, generate it into a dynamic child pipeline instead of interpolating parallel:.

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.