Troubleshooting Common Issues
1. Resolving Runner Connection Issues
| Issue | Symptoms | Possible Causes | Solution |
|---|---|---|---|
| Runner not connecting | Runner shows as "offline" in GitLab UI Job logs show "Runner not responding" |
Network issues Incorrect runner registration token Firewall blocking connections |
Verify runner token matches GitLab Check network connectivity to GitLab instance Ensure port 443 is open |
| Runner timeout errors | Jobs hang or timeout Logs show "timeout waiting for response" |
Slow network Runner resource constraints High job load |
Optimize runner resources Reduce concurrent jobs Improve network performance |
| Authentication failure | Runner logs show "401 Unauthorized" Job fails with auth error |
Expired registration token Incorrect runner configuration GitLab instance URL mismatch |
Re-register runner with new token Verify GitLab URL in config Check token validity |
Example: Re-registering a GitLab Runner
# Unregister existing runner
sudo gitlab-runner unregister --name "my-runner"
# Register new runner with updated token
sudo gitlab-runner register \
--url "https://gitlab.example.com/" \
--registration-token "new-registration-token" \
--executor "shell" \
--name "my-runner"
Note: Ensure the runner's registration token is valid and matches the one in GitLab's CI/CD settings.
Warning: If runners are behind a firewall or proxy, ensure proper configuration to allow outbound connections to GitLab.
2. Fixing Docker Authentication Errors
| Issue | Solution | Notes |
|---|---|---|
| Unauthorized access to registry | docker login <registry> |
Ensure credentials are correctly set in GitLab CI/CD variables |
| Invalid token or credentials | Re-generate and reconfigure registry credentials | Use CI_REGISTRY_USER and CI_REGISTRY_PASSWORD for GitLab-managed registry |
| Permission denied for image pull/push | Verify project access rights and group permissions | Check that the GitLab runner has appropriate roles to access the registry |
Example: Setting up Docker registry credentials in GitLab CI
variables:
DOCKER_REGISTRY: "registry.gitlab.com"
DOCKER_IMAGE: "$DOCKER_REGISTRY/$CI_PROJECT_PATH"
before_script:
- echo "Logging into Docker registry..."
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $DOCKER_REGISTRY
build_job:
stage: build
image: docker:latest
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
Note: Ensure
CI_REGISTRY_USER and CI_REGISTRY_PASSWORD are properly configured in GitLab CI/CD variables or protected secrets.
Warning: Avoid hardcoding credentials in .gitlab-ci.yml files. Use GitLab's built-in CI/CD variables or secret variables.
3. Debugging Cache Miss Issues
| Issue | Description | Solution |
|---|---|---|
| Cache key mismatch | Cache is not hit due to different cache keys between jobs. | Ensure consistent cache key across jobs using cache:key with same values. |
| Cache path mismatch | Cache paths do not match between job runs. | Verify cache:path matches exactly in all jobs using the cache. |
| Cache TTL expiration | Cache is invalidated due to time-to-live (TTL) limits. | Adjust cache:ttl or use cache:key with versioning to prevent premature invalidation. |
Note: Use
CI_COMMIT_REF_SLUG to ensure cache keys are consistent across branches.
Warning: Avoid using
$CI_COMMIT_SHA in cache keys if you want to reuse cache across different commits.
4. Resolving Artifact Download Failures
| Issue | Cause | Solution |
|---|---|---|
| Artifacts not found | Artifacts were not uploaded correctly or path is incorrect | Verify artifacts.path in job configuration and ensure artifacts are uploaded before download |
| Permission denied | Job does not have access to artifacts from previous stages | Ensure artifacts.expire_in is set appropriately and job has correct permissions |
| Timeout during download | Large artifact size or slow network | Use artifacts.when: on_failure or split artifacts into smaller chunks |
Example: Artifact Upload and Download Configuration
job1:
script:
- echo "Hello World" > output.txt
artifacts:
paths:
- output.txt
expire_in: 1 day
job2:
script:
- cat output.txt
needs:
- job: job1
artifacts: true
Note: Artifacts are only available within the same pipeline unless
artifacts.expire_in is set to a longer duration.
Warning: If
artifacts.when is set to on_failure, artifacts will only be uploaded if the job fails.
5. Fixing YAML Syntax Errors
| Issue | Description | Solution |
|---|---|---|
| Incorrect Indentation | YAML is sensitive to indentation. Misaligned spaces or tabs can cause parsing errors. | Ensure consistent use of 2 spaces for indentation. Avoid mixing tabs and spaces. |
| Missing Colon | YAML requires a colon after keys in key-value pairs. | Add the missing colon: key: value. |
| Unescaped Special Characters | Characters like :, {, [, & must be escaped or quoted. |
Wrap problematic values in quotes: key: "value:with:colon". |
| Unquoted Values with Special Characters | Values containing special characters without quotes can cause parsing errors. | Use double quotes for values with special characters: key: "{value}". |
Example: Correct YAML Syntax
stages:
- build
- test
build_job:
stage: build
script:
- echo "Building..."
- echo "Build completed"
test_job:
stage: test
script:
- echo "Testing..."
- echo "Test completed"
Example: Incorrect YAML Syntax
stages:
- build
- test
build_job:
stage: build
script:
- echo "Building..."
- echo "Build completed"
test_job:
stage: test
script:
- echo "Testing..."
- echo "Test completed"
Note: Use a YAML validator or GitLab CI Linter to catch syntax errors before committing.
6. Debugging Variable Expansion Issues
| Variable Type | Expansion Behavior | Debugging Tips |
|---|---|---|
| CI/CD Variables | $VAR_NAME or ${VAR_NAME} |
Use echo $VAR_NAME to verify expansion in job logs |
| Predefined Variables | Automatically expanded by GitLab | Check echo $CI_PIPELINE_ID to confirm value |
| Custom Variables | Must be defined in project/group/runner settings | Verify variable visibility scope (CI/CD, protected, etc.) |
Example: Variable Expansion in Script
script:
- echo "Pipeline ID: $CI_PIPELINE_ID"
- echo "Branch Name: $CI_COMMIT_REF_NAME"
- echo "Custom Var: $CUSTOM_VAR"
Note: Variables defined in a job's
variables block are expanded at runtime, not at parse time.
Warning: Using
$VAR_NAME without braces can lead to unexpected expansion if the variable name is followed by alphanumeric characters.
Common Expansion Issues
- Unexpanded Variables: Ensure variables are defined in the correct scope (e.g., project, group, or runner settings).
- Incorrect Syntax: Use
${VAR_NAME}instead of$VAR_NAMEto avoid ambiguity. - Variable Scope: Variables set in a job do not propagate to downstream jobs unless explicitly passed via
artifactsordependencies.
7. Resolving Permission Denied Errors
| Error Message | Cause | Solution |
|---|---|---|
| Permission denied (publickey) | SSH key not configured or invalid | Ensure SSH key is added to GitLab and matches local key |
| Permission denied (access) | Insufficient access level to repository | Verify user has at least Developer access or higher |
| 403 Forbidden | Token or credential invalid | Regenerate personal access token with correct scope |
Example: Setting up SSH Keys for GitLab CI
ssh-keygen -t rsa -b 4096 -C "gitlab-ci@example.com"
ssh-add ~/.ssh/id_rsa
Note: Ensure the public key is added to your GitLab account under
Settings > SSH Keys.
Warning: Never commit SSH private keys to repositories or expose them in job logs.
Common Permission Issues
- SSH Key Mismatch - Ensure local and GitLab keys match
- Access Level - Users must have appropriate project permissions
- Token Expiry - Personal access tokens may expire and require regeneration
8. Fixing Timeout Issues
| Issue | Solution | Notes |
|---|---|---|
| Job exceeds timeout | timeout: 30 minutes in job config |
Default is 1 hour; adjust as needed |
| Runner hangs on startup | timeout: 10 minutes in config.toml |
Adjust runner-specific timeout settings |
| Network request timeouts | Use retry: with max_attempts: 3 |
Retry logic can prevent transient network issues |
Note: Use
timeout in job config to set per-job limits. For runner-level timeouts, adjust config.toml.
Warning: Setting timeouts too low may cause jobs to fail prematurely. Ensure sufficient time for builds and tests.
9. Debugging Merge Conflict Failures
| Issue | Description | Solution |
|---|---|---|
| Merge conflict in pipeline | Conflicts occur when GitLab attempts to merge branches and cannot automatically resolve differences. | Manually resolve conflicts in the codebase before re-running the pipeline or using git merge locally. |
| Pipeline fails due to unmerged changes | When a merge request has unmerged changes, GitLab may fail to run the pipeline. | Ensure all changes are merged into the target branch before triggering a pipeline or use git rebase to resolve conflicts. |
Example: Resolving Merge Conflicts Locally
git checkout feature-branch
git rebase main
# Resolve conflicts in editor
git add .
git commit -m "Resolve merge conflict"
git push --force-with-lease
Note: Merge conflicts in CI/CD pipelines often stem from changes in the target branch that are not reflected in the feature branch. Always ensure your local branch is up to date with the latest changes from the target branch before merging.
10. Resolving Resource Exhaustion
| Issue | Symptoms | Potential Causes | Solutions |
|---|---|---|---|
| High CPU Usage | builds timing out, runner lagging |
too many concurrent jobs, inefficient scripts |
Reduce concurrent jobs, optimize scripts |
| Memory Exhaustion | builds failing with OOM errors |
large artifacts, memory leaks in scripts |
Limit artifact size, use memory-efficient tools |
| Disk Space Full | builds failing with disk space errors |
unmanaged cache, large logs |
Set up cleanup jobs, configure cache limits |
Example: Setting Cache Limits
cache:
key: "${CI_COMMIT_REF_SLUG}"
paths:
- node_modules/
policy: pull-push
Note: Use
git gc in cleanup scripts to reduce repository size.
Warning: Excessive cache usage can lead to disk space exhaustion.