Skip to main content
This guide shows how to diagnose canceled GitHub Actions jobs that run on self-hosted runners. We’ll:
  • Create a simple workflow that simulates a long-running telemetry stream.
  • Run it on a self-hosted runner and cancel it from the GitHub Actions UI.
  • Inspect the runner process, _work and _diag directories to determine why the job was canceled.
Keywords: GitHub Actions self-hosted runner diagnostics, canceled job, _diag logs, ACTIONS_RUNNER_DEBUG, ACTIONS_STEP_DEBUG.

1. Create the workflow

Create a new workflow file (for example, .github/workflows/rocket-launch.yml) with this content. It triggers on pushes and manual workflow_dispatch events, runs on a self-hosted runner, and includes a 10-minute timeout. The single step prints telemetry every 5 seconds for 60 seconds.
This workflow will appear in GitHub Actions and can be started manually (workflow_dispatch) or by pushing to the repository.

2. Run the job and cancel it from the GitHub Actions UI

Start the workflow (push or manual trigger). If you cancel the running workflow from the GitHub Actions UI while the step is executing, the job log will show the running shell output and then an error like:
At this point the UI shows the job as canceled. To determine why it was canceled and how the runner handled the shutdown, inspect the self-hosted runner host directly.
A dark-themed GitHub Actions page for a repository, showing the "Rocket Launch Telemetry Demo" workflow with its run history and a notice about an upcoming GitHub App installation token format change. The left sidebar lists other workflows and management options like Caches and Runners.

3. Inspect the self-hosted runner process

On the self-hosted runner host, start or watch the runner with the provided run.sh script:
If you cancel the job from the UI, the runner process output records the cancellation:
The runner repo directory typically contains _work (job working directories) and _diag (diagnostic logs). List the runner directory:

4. Explore _work — job working directories and temp files

Inspect _work to find per-run directories, checked-out repositories, and temporary files:
Useful quick-checks:
  • Look for the temp script run by the step in _work/_temp/.
  • Check the workspace for artifacts or partial output that may indicate abrupt termination.

5. Check diagnostic logs in _diag

The _diag folder contains the most useful files for deep debugging: Runner_* and Worker_* logs. List them:
Search for cancellation-related entries. Common greps:
  • cancel
  • Operation canceled
  • Force kill process on cancellation
  • BrokerServer
Example: find canceled socket operations:
This output indicates the runner’s broker connection encountered a canceled socket operation — consistent with an API-initiated cancellation or a network/transport failure. Other _diag entries to watch for:
  • Force kill process on cancellation: 'False' means the runner tries a graceful shutdown of child processes instead of forcing them to exit immediately.

6. Results upload and cleanup after cancellation

Even after a cancel, the runner typically tries to upload step logs and job logs to the results service and then cleans up temporary directories:
This confirms logs are preserved and uploaded — allowing you to continue debugging via the GitHub UI.

7. Enable more verbose debugging

To get more detailed information during execution:
  • Enable workflow step debug logging by setting the repository secret ACTIONS_STEP_DEBUG to true.
  • Enable runner debug logging by setting the repository secret ACTIONS_RUNNER_DEBUG to true (or enable it via runner configuration locally).
Placeholders for these were included as commented-out steps in the example workflow above.
Enable ACTIONS_STEP_DEBUG and/or ACTIONS_RUNNER_DEBUG only temporarily. Debug logs are very verbose and can expose sensitive data — do not leave these enabled in production long-term.
When step debug is enabled, the job log includes ##[debug] lines. Example showing a step aborted with exit code 130 (SIGINT / CTRL-C):
  • Exit code 130 typically indicates termination by SIGINT (signal 2 / user cancel). Different exit codes point to other termination reasons.

8. Quick reference — runner folders and useful grep terms

Common grep terms to find cancellation context:
  • cancel
  • Operation canceled
  • Force kill process on cancellation
  • BrokerServer
  • ProcessInvokerWrapper

9. Troubleshooting checklist

  • Check the GitHub Actions job log first for step output and any Error: The operation was canceled. messages.
  • On the runner host:
    • Inspect _work/ for the workspace and temp scripts.
    • Inspect _diag/ (Runner_* and Worker_* logs) for detailed traces, socket errors, stack traces, and upload activity.
  • Grep _diag logs for the terms listed above to quickly locate cancellation-related traces.
  • Confirm whether the runner process was stopped (e.g., ^C, service restart) — stopping the runner while jobs are running causes the server to mark them canceled.
  • If you need deeper information, enable ACTIONS_STEP_DEBUG and/or ACTIONS_RUNNER_DEBUG temporarily and rerun the workflow.
  • Determine if the cancel came from:
    • A user/API call (UI cancel or REST API)
    • Runner process termination
    • Network/transport error that aborted the broker connection
Using the job log together with _diag and _work inspection will let you determine whether a cancel was user-initiated, runner-initiated (shutdown), or caused by an underlying transport/socket error.

Watch Video