Summary
A self-hosted GitHub Actions runner can fail during boot if the machine's system clock has not yet synchronized.
When this happens, GitHub rejects the runner's OAuth token because the local clock is significantly behind the GitHub server time. However, the runner reports:
Failed to create a session. The runner registration has been deleted from the server, please re-configure.
Runner registrations are automatically deleted for runners that have not connected to the service recently.
This message is misleading because the runner registration has not actually been deleted.
More importantly, the runner exits and does not retry after the system clock becomes synchronized. Since the systemd service then remains inactive, the self-hosted runner stays offline until manually restarted.
Environment
- Self-hosted GitHub Actions runner
- Runner version:
2.336.0
- Linux / Raspberry Pi
- Runner installed using
svc.sh
- systemd
systemd-timesyncd
- Runner service enabled at boot
What happened
The runner service started correctly during boot:
Aug 24 15:10:40 systemd[1]: Started GitHub Actions Runner
The runner successfully reached GitHub:
But session creation failed:
POST request to https://tokenghub.actions.githubusercontent.com/... failed.
HTTP Status: BadRequest
The underlying exception contained the actual cause:
GitHub.Services.OAuth.VssOAuthTokenRequestException:
The token expired on 08/24/2026 19:15:44.
Current server time is 08/25/2026 01:44:14.
The system clock was several hours behind because NTP synchronization had not completed yet.
The runner then converted this into:
Failed to create a session. The runner registration has been deleted from the server, please re-configure.
and exited:
Runner listener exited with error code 1
Runner listener exit with terminated error, stop the service, no retry needed.
Several hours later, after NTP synchronized the system clock, simply running:
caused the same runner registration to connect successfully:
√ Connected to GitHub
Current runner version: '2.336.0'
Listening for Jobs
No re-registration or configuration change was required.
Expected behavior
The runner should ideally detect this situation and handle it gracefully.
For example:
- If OAuth authentication fails because a token appears expired but the server time differs significantly from the local clock, report a clock-skew-specific error.
- Retry session creation for some period instead of permanently terminating the runner service.
- Avoid reporting that the runner registration has been deleted unless the server has actually confirmed that condition.
A message such as:
Authentication failed because the system clock appears to differ significantly from GitHub server time.
Check NTP/time synchronization. Retrying...
would make the actual problem much easier to diagnose.
Current workaround
I added the following systemd dependency to prevent the runner from starting before time synchronization:
[Unit]
Wants=network-online.target systemd-time-wait-sync.service
After=network-online.target systemd-time-wait-sync.service
This prevents the issue on systems using systemd-timesyncd, but it is platform-specific and shouldn't be necessary for the runner to recover from temporary clock skew.
Suggested improvement
The runner does not necessarily need to manage system time itself.
However, session/authentication failures caused by clock skew should be treated as potentially transient.
In particular, the runner could:
- distinguish clock-skew/token-time errors from deleted runner registrations;
- retry authentication with exponential backoff;
- log the local and GitHub server time when a significant discrepancy is detected;
- remain running so that it can reconnect once NTP corrects the clock.
This would make self-hosted runners much more resilient after reboots, power loss, RTC issues, or delayed NTP synchronization.
github-runner-clock-skew-report.txt
Summary
A self-hosted GitHub Actions runner can fail during boot if the machine's system clock has not yet synchronized.
When this happens, GitHub rejects the runner's OAuth token because the local clock is significantly behind the GitHub server time. However, the runner reports:
This message is misleading because the runner registration has not actually been deleted.
More importantly, the runner exits and does not retry after the system clock becomes synchronized. Since the systemd service then remains inactive, the self-hosted runner stays offline until manually restarted.
Environment
2.336.0svc.shsystemd-timesyncdWhat happened
The runner service started correctly during boot:
The runner successfully reached GitHub:
But session creation failed:
The underlying exception contained the actual cause:
The system clock was several hours behind because NTP synchronization had not completed yet.
The runner then converted this into:
and exited:
Several hours later, after NTP synchronized the system clock, simply running:
caused the same runner registration to connect successfully:
No re-registration or configuration change was required.
Expected behavior
The runner should ideally detect this situation and handle it gracefully.
For example:
A message such as:
would make the actual problem much easier to diagnose.
Current workaround
I added the following systemd dependency to prevent the runner from starting before time synchronization:
This prevents the issue on systems using
systemd-timesyncd, but it is platform-specific and shouldn't be necessary for the runner to recover from temporary clock skew.Suggested improvement
The runner does not necessarily need to manage system time itself.
However, session/authentication failures caused by clock skew should be treated as potentially transient.
In particular, the runner could:
This would make self-hosted runners much more resilient after reboots, power loss, RTC issues, or delayed NTP synchronization.
github-runner-clock-skew-report.txt