Introduction

GitHub Actions workflows fail during execution. Steps return non-zero exit codes, runners encounter errors, or workflow syntax is invalid.

Symptoms

Workflow failed:

bash
Run ./.github/workflows/ci.yml
Error: Process completed with exit code 1.

Step failed:

bash
Run npm test
Error: npm ERR! Test failed.  See above for more details.
Error: Process completed with exit code 1.

Runner error:

bash
Error: The runner was unable to complete the job due to an unexpected error.

Common Causes

  1. 1.Syntax error - Invalid workflow YAML syntax
  2. 2.Missing secrets - Required secrets not configured
  3. 3.Step failure - Command returns non-zero exit code
  4. 4.Timeout - Job exceeds time limit
  5. 5.Runner issues - Self-hosted runner problems
  6. 6.Dependency failure - Previous step failed
  7. 7.Permission denied - Insufficient permissions

Step-by-Step Fix

Step 1: Check Workflow Syntax

```bash # Validate workflow syntax locally: # Use actionlint: actionlint .github/workflows/ci.yml

# Use yamllint: yamllint .github/workflows/ci.yml

# Check YAML parsing: python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))"

# Common syntax errors: # - Incorrect indentation # - Missing required fields # - Invalid action reference # - Wrong condition syntax

# View workflow in GitHub UI: # Actions -> Workflows -> ci.yml -> View workflow file ```

Step 2: Check Failed Step Logs

```bash # View logs in GitHub UI: # Actions -> Run -> Failed job -> Failed step

# Download logs via API: gh run download RUN_ID

# View logs locally: cat logs/job-1/step-1.txt

# Check step output: gh run view RUN_ID --log | grep -A 50 "step-name"

# Look for: # - Error messages # - Exit codes # - Stack traces # - Timeout messages ```

Step 3: Check Secrets and Environment

```bash # Check if secrets configured: # Repository -> Settings -> Secrets and variables -> Actions

# List secrets via API: gh secret list

# Check environment variables in workflow: env: MY_VAR: ${{ secrets.MY_SECRET }}

# Common secret issues: # - Secret name case mismatch # - Secret not set # - Secret empty

# Debug secrets (DO NOT print secrets): - name: Check secret exists if: ${{ secrets.MY_SECRET == '' }} run: echo "Secret not set" ```

Step 4: Check Runner Status

```bash # For self-hosted runners:

# List runners: gh api repos/OWNER/REPO/actions/runners | jq '.runners[] | {name: .name, status: .status}'

# Check runner logs: # On runner host: journalctl -u actions.runner.* -f

# Check runner process: ps aux | grep runner

# Runner diagnostics: ./run.sh --diagnostic

# Check runner disk space: df -h

# Check runner memory: free -h

# Restart runner: systemctl restart actions.runner.* ```

Step 5: Debug Workflow Locally

```bash # Use act to run workflows locally: act -j job-name

# Run specific event: act push

# Run with secrets: act -s MY_SECRET=secret-value

# Dry run: act -n

# List jobs: act -l

# Run with specific platform: act -P ubuntu-latest=node:16 ```

Step 6: Check Step Conditions

```bash # Steps may be skipped due to conditions:

# Check if condition: - name: Run tests if: github.event_name == 'push'

# Check previous step success: - name: Deploy if: success()

# Check previous step failure: - name: Notify on failure if: failure()

# Always run: - name: Cleanup if: always()

# Matrix combinations: - name: Test if: matrix.node-version == '16'

# Check step was executed: gh run view RUN_ID --log | grep "step-name" ```

Step 7: Check Timeout Settings

```bash # Default timeout is 6 hours (360 minutes)

# Check timeout settings: jobs: build: timeout-minutes: 30

# Step-level timeout: steps: - name: Long running timeout-minutes: 10

# Check timeout in logs: gh run view RUN_ID --log | grep -i "timeout"

# Increase timeout if needed: jobs: build: timeout-minutes: 60 ```

Step 8: Check Permissions

```bash # Check GITHUB_TOKEN permissions: jobs: build: permissions: contents: read packages: write

# Check repository permissions: # Settings -> Actions -> General -> Workflow permissions

# Read/write permissions: permissions: contents: write pull-requests: write

# Check permission errors in logs: gh run view RUN_ID --log | grep -i "permission|forbidden|unauthorized"

# Debug token: - name: Debug token run: echo "${{ github.token }}" | md5sum # DO NOT print actual token ```

Step 9: Check Matrix and Strategy

```bash # Matrix configuration issues:

# Check matrix definition: strategy: matrix: node: [14, 16, 18] os: [ubuntu-latest, macos-latest]

# Check fail-fast: strategy: fail-fast: false

# Check max-parallel: strategy: max-parallel: 4

# Debug matrix values: - name: Debug matrix run: | echo "Node: ${{ matrix.node }}" echo "OS: ${{ matrix.os }}" ```

Step 10: Monitor Workflow Runs

```bash # List recent runs: gh run list --limit 10

# View run details: gh run view RUN_ID

# Watch running workflow: gh run watch RUN_ID

# Check run status: gh run view RUN_ID --json status,conclusion

# List failed runs: gh run list --status failure --limit 10

# Rerun workflow: gh run rerun RUN_ID

# Rerun failed jobs: gh run rerun RUN_ID --failed

# Check workflow usage: gh api repos/OWNER/REPO/actions/workflows | jq ```

GitHub Actions Workflow Failed Checklist

CheckCommandExpected
Workflow syntaxactionlintNo errors
Secrets configuredgh secret listRequired secrets
Runner statusgh api runnersonline
Step logsgh run viewNo errors
Permissionsworkflow fileCorrect
Timeouttimeout-minutesSufficient

Verification

```bash # 1. Validate syntax actionlint .github/workflows/ci.yml // No errors

# 2. Test locally with act act -j build // Succeeds locally

# 3. Push changes git push // Triggers workflow

# 4. Watch workflow gh run watch // All steps pass

# 5. Check conclusion gh run view --json conclusion // success

# 6. Verify logs gh run view --log | grep -i error // No errors ```

  • [Fix GitLab CI Pipeline Stuck](/articles/fix-gitlab-ci-pipeline-stuck)
  • [Fix Jenkins Build Stuck](/articles/fix-jenkins-build-stuck)
  • [Fix Jenkins Pipeline Failed](/articles/fix-jenkins-pipeline-failed)
  • [Technical troubleshooting: Fix Cicd Artifact Upload Failed Storage Issue in C](cicd-artifact-upload-failed-storage)
  • [Technical troubleshooting: Fix Cicd Code Quality Gate Failed Sonarqube Issue ](cicd-code-quality-gate-failed-sonarqube)
  • [Technical troubleshooting: Fix Cicd Deployment Failed Health Check Issue in C](cicd-deployment-failed-health-check)
  • [Technical troubleshooting: Fix Cicd Github Actions Workflow Queue Timeout in ](cicd-github-actions-workflow-queue-timeout)
  • [Technical troubleshooting: Fix Cicd Gitlab Runner Stuck Pending Issue in CI/C](cicd-gitlab-runner-stuck-pending)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix GitHub Actions Workflow Failed", "description": "Troubleshoot GitHub Actions workflow failed. Check syntax, runner, steps.", "url": "https://www.fixwikihub.com/fix-github-actions-workflow-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-11T18:12:14.414Z", "dateModified": "2026-04-11T18:12:14.414Z" } </script>