Disappearing GitHub Self-Hosted Runner

Published: April 9, 2025

GitHub ActionsDevOpsSelf-Hosted RunnersIssues

I had two GitHub Actions runners installed on a DigitalOcean droplet. I noticed that one of them had disappeared from GitHub. Locally the service was still running, but GitHub no longer showed it in the runner list.

TL;DR: GitHub automatically removes self-hosted runners that don’t pick up a job for more than 14 days. The runner on my droplet hadn’t been used during that period, so GitHub cleaned it up.


Debugging

At first, I checked the runner status:

sudo systemctl status actions.runner.<org>-<repo>-<name>.service

The service was active, so I restarted it:

sudo systemctl restart actions.runner.<org>-<repo>-<name>.service

But GitHub still didn’t recognize it. I also tried:

./config.sh remove
./config.sh

The remove step failed because GitHub had already deleted the runner. At this point it was clear: the local service thought it was fine, but GitHub had removed the registration.

Solution

The fix was to wipe the old runner and set up a new one.

# stop and remove
sudo systemctl stop actions.runner.<org>-<repo>-<name>.service
rm -rf actions-runner

# download fresh runner
curl -o actions-runner-linux-x64.tar.gz -L https://github.com/actions/runner/releases/latest/download/actions-runner-linux-x64.tar.gz
tar xzf ./actions-runner-linux-x64.tar.gz

# register again
./config.sh --url https://github.com/<org>/<repo> --token <new-token-from-repo-settings>
sudo ./svc.sh install
sudo ./svc.sh start

After this, the runner showed up in GitHub again and started picking jobs normally.

Side Effect

Right after reinstalling, my website showed an Nginx “Bad Gateway” error. This happened because the new runner had no _work directory yet. GitHub creates that folder only when a workflow runs. After triggering a deployment, the files were back in place and Nginx worked fine.

Preventing It

To avoid this in the future, I added a scheduled workflow to keep the runner active. It runs every 7 days at midnight:

name: Alive Check - Keep Runner Active

on:
  schedule:
    - cron: '0 5 1,10,20 * *' # Runs at 5 AM UTC on the 1st, 10th, and 20th of every month
  workflow_dispatch: # Allows manual triggering, where you can click a button to manually run this workflow

jobs:
  keep_runner_active:
    runs-on: self-hosted
    steps:
      - name: Keep runner active
        run: echo "Keeping runner active at $(date)"

      - name: Restart  application
        run: |
          cd /home/<user_name>/<actions_runner_name>/_work/project_name
          pm2 restart 1

Let's connect

Always interested in good conversations about technology, football, or interesting projects.