We recommend checking host reachability, Runner service state, and GitHub connectivity in that order after a Mac restart; verify labels and group access only after the Runner can communicate. Do not remove and re-register the Runner as a first response. Resume production dispatch only after a representative workflow accepts a job, builds successfully, and returns its result.
This guide is for platform engineers managing GitHub Actions self-hosted runners, enterprise IT owners responsible for Mac CI recovery, and release leads who need evidence that a build pipeline—not just a Runner status—has recovered.
Host access before Runner registration
A Runner shown as Offline does not prove that its registration is broken. GitHub identifies several possible causes, including an unavailable host, a stopped Runner application, or a communication problem. We first separate those causes instead of changing Runner registration blindly. GitHub’s troubleshooting guidance describes the Offline state and its diagnostic direction.
Why can a Runner show Offline after a Mac restart?
The Mac may be powered off, still starting, waiting for a user session, unreachable through the remote-management path, or running without a functioning Runner application. These conditions can look identical in the GitHub interface. Check the host and Runner separately.
Use this sequence:
- [ ] Check whether the Mac is powered on and has completed startup, using your approved device-management or facilities records.
- [ ] Attempt the team’s normal remote access method. Record whether the host itself responds, not just whether the GitHub page changes.
- [ ] Check recent restart, power, network, and maintenance records for the host.
- [ ] Compare that evidence with the Runner’s status in GitHub.
- [ ] Record the first point of failure before restarting services or changing configuration.
If remote access fails, treat the incident as a host availability problem until evidence says otherwise. Restarting or re-registering the Runner cannot repair a Mac that has not booted or cannot reach the management network.
If the host is reachable but GitHub still reports Offline, continue to the service check. If the host is reachable only after a user signs in, record that dependency: it can distinguish a user-session service from a system service and may explain why an unattended restart does not restore CI.
Operations note: Keep the host check independent of the GitHub status page. A single “Offline” signal cannot distinguish power, startup, service, and network failures.
Runner service state versus a logged-in session
A running Mac does not mean its Runner service has started. The Runner may have been installed as a service but failed to start, or it may have been launched in a user session that is no longer available after reboot.
GitHub documents the service management script for self-hosted runners. From the Runner installation directory, check the installed service with ./svc.sh status. If the service is present but stopped, use ./svc.sh start according to the team’s change procedure. The GitHub service configuration instructions cover service setup and management.
How do we confirm that the Runner service started on macOS?
Check the service state with the Runner’s svc.sh script, then compare it with the Runner’s GitHub status and the service logs. A successful command alone is not enough: the Runner must also connect to GitHub and become available for the intended job.
macOS uses launchd to manage services, but a LaunchAgent and a LaunchDaemon run in different contexts. A LaunchAgent is associated with a user session; a LaunchDaemon is managed in a system context. The exact behavior depends on the service configuration. Do not infer that a Runner will start before login merely because it starts correctly in an interactive shell. Apple’s Service Management documentation describes these service contexts.
For diagnosis, check:
- Whether the Runner service was installed and is present in the expected context.
- Whether the service state reported by
./svc.sh statusagrees with the GitHub Runner page. - Whether startup depends on a user login, credentials, or other local prerequisites.
- Whether the Runner’s
_diaglogs show a startup failure or an unexpected shutdown. - Whether a recent macOS update, maintenance action, or service change preceded the incident.
Do not create or edit launchd configuration based only on a guessed service label. Confirm the installed service definition first. Keep a copy of the current configuration and follow the team’s approval process before modifying it.
Local process versus GitHub connectivity
A Runner process can be running and still fail to communicate with GitHub. Basic browsing from the Mac does not establish that the Runner can reach every service it needs. DNS resolution, proxy configuration, TLS inspection, firewall rules, and outbound policy can affect the Runner differently from an interactive browser.
What should we check when the process runs but GitHub still shows Offline?
Start with the Runner’s own connectivity check and diagnostic logs. Then compare the failing destination and network path with the organization’s DNS, proxy, firewall, and TLS policies. Do not disable certificate validation to make a test pass.
From the Runner installation directory, GitHub documents ./config.sh --check as a connectivity check. Run it as an authorized operator and review the reported results. The same GitHub troubleshooting guide explains the diagnostic path. If the environment requires a proxy, check that the Runner is configured for it using GitHub’s self-hosted Runner proxy guidance.
The _diag directory is a key source of Runner-side evidence. Review the logs around the restart and the first failed connection. Look for whether the Runner started, attempted to connect, and then encountered a repeated network or authentication error. When a workflow is needed to add detail, GitHub documents how to enable workflow and Runner debug logging. Treat debug output as potentially sensitive; store and share it according to internal policy.
A useful troubleshooting distinction is:
- DNS failure: the Runner cannot resolve a required destination. Check the resolver and network policy used by the host.
- Proxy mismatch: the host can browse through a proxy, but the Runner process is not using the same approved proxy path. Validate the service environment and documented proxy settings.
- TLS or certificate failure: inspect the certificate chain and any authorized inspection layer. Do not bypass TLS verification as a workaround.
- Firewall or egress restriction: compare permitted outbound access with the organization’s current GitHub Actions network requirements.
- Authentication or configuration error: read the Runner logs before changing registration. The error may concern configuration or credentials rather than basic network reachability.
If the connectivity check fails, preserve its output with the relevant logs and send the evidence to the network or platform owner. If it passes but GitHub still shows Offline, compare timestamps: the local check and GitHub status may reflect different attempts. Check for a continuing service error before attempting registration changes.
Online Runner versus eligible job
A Runner marked Online may still leave a workflow waiting. GitHub assigns jobs based on the workflow’s runs-on requirements and the Runner’s labels, as well as group and repository access. The Runner selection documentation explains job routing. GitHub also documents Runner labels and Runner group access.
Why is a job queued when the Runner is online?
Compare the workflow’s runs-on expression with the Runner’s actual labels, then confirm that its group is available to the repository or organization context that needs the job. A live Runner that does not satisfy the job’s routing conditions will not pick up that job.
Check the workflow file and the Runner’s GitHub settings side by side. Confirm the operating-system and architecture labels the job requests, any custom labels added by the team, and the group that contains the Runner. Do not assume that a label present on a different Mac or an earlier Runner registration is present on the current one.
If the workflow requests a custom label, verify the exact spelling and assignment. If the job is restricted to a Runner group, confirm the group’s repository access. When labels and access appear correct, examine the workflow run’s queued-job message for the unmet requirement. That message is often more useful than changing the Runner configuration speculatively.
A practical routing check separates four facts:
- The Runner is registered and shown as online.
- The Runner has the labels requested by the job.
- The job’s repository or organization can use the Runner’s group.
- The workflow has no additional condition that prevents the job from being assigned.
Only after those checks should we consider whether the job has an unrelated dependency, approval, or workflow-level condition that keeps it queued.
Duplicate records versus a genuine recovery failure
An old Runner entry, a duplicate service, or a mismatched Runner name can make the status picture confusing. That does not mean every Offline Runner should be removed. Re-registration can discard useful evidence and create another record without fixing the underlying host, service, or network problem.
Start by comparing the Runner name and group in GitHub with the local Runner configuration and installed service. Look at the timestamps and logs around the restart. Check whether the Mac is running the expected service, whether the current Runner identity is the one shown in GitHub, and whether a second entry may belong to a replaced host.
Use this decision path:
- If the host is unreachable: resolve host power, startup, or remote-access issues first; do not re-register.
- If the host is reachable and the service is stopped: inspect service installation and launch context; start the existing service only after confirming it is the intended installation.
- If the service runs but connectivity checks fail: resolve DNS, proxy, TLS, or egress issues before changing Runner registration.
- If the Runner is online but the job waits: correct label, group, or repository access conditions.
- If logs and configuration show a stale or invalid registration: follow the approved remove-and-configure process, then verify that the old record and service no longer conflict.
GitHub’s Runner configuration instructions provide the supported configuration context. Use them when evidence points to registration itself, not as a generic recovery shortcut.
Recovery acceptance before production dispatch
An Offline-to-Online transition confirms only that the Runner has reconnected. It does not prove that the Mac can accept the relevant job, access its workspace, use required tools, or return a valid build result. We keep production dispatch gated until the intended workflow path has been tested.
How do we know the workflow can accept jobs after recovery?
Run a representative, low-risk workflow that exercises the same Runner labels and group as production. Confirm job assignment, workspace access, required tool invocation, and result upload. Keep production signing assets and release actions out of the test unless the release owner has explicitly approved them.
Use this acceptance sequence:
- [ ] Confirm the host is reachable through the normal operations path.
- [ ] Confirm the expected Runner service is installed and its state is healthy.
- [ ] Confirm GitHub shows the intended Runner online.
- [ ] Confirm the test job routes to that Runner through the intended labels and group.
- [ ] Run a representative build or validation task that does not access production signing assets.
- [ ] Check the workflow logs for tool execution, artifact or result handling, and successful completion.
- [ ] Have the pipeline owner apply the team’s release gate before restoring production dispatch.
- [ ] Record the failure cause, change made, and acceptance evidence for the next incident.
| Recovery layer | Evidence to collect | Pass condition |
|---|---|---|
| Host | Approved remote access and operational records | The Mac is reachable and startup is complete |
| Service | ./svc.sh status, service configuration, and _diag logs |
The intended Runner service is active and its logs show no unresolved startup failure |
| Connectivity | ./config.sh --check output and relevant network logs |
The Runner can complete the documented connectivity checks |
| Routing | Workflow runs-on, Runner labels, group, and repository access |
The test job is eligible for this Runner |
| Pipeline | Representative workflow result | The job is accepted, required steps run, and results return |
| Observed state | Likely fault domain | Next action |
|---|---|---|
| Host cannot be reached | Power, startup, or management network | Restore host access and verify startup before Runner changes |
| Host responds; service is stopped | Service installation or launch context | Inspect the installed service and start the intended service |
| Service runs; connectivity check fails | DNS, proxy, TLS, or outbound policy | Diagnose the failing network path without bypassing TLS |
| Runner online; job remains queued | Labels, group, or repository access | Compare workflow routing conditions with Runner settings |
| Test job succeeds; production remains gated | Release policy or signing boundary | Ask the release owner to approve production dispatch |
| Recovery option | Appropriate when | Trade-off to review |
|---|---|---|
| Repair the existing Runner | The host and registration are valid, with a clear service or network fault | Keeps the current identity, but requires verifying that the underlying fault is resolved |
| Reconfigure the Runner | Logs and configuration show a genuine registration problem | Can remove useful evidence or create conflicting records if done without diagnosis |
| Move work to another Mac node | The current host cannot meet the required recovery or isolation needs | Requires checking toolchain parity, job routing, credentials, and operational ownership |
| Use a remote Mac resource | The team needs an alternative hosted Mac environment for a defined workload | Review access, delivery, security, operations, and cost terms before assigning CI work |
For teams comparing where to run Mac CI, MESHLAUNCH’s remote Mac options can be considered alongside owned hardware and other approved hosting arrangements. A Mac mini remote option is another point of comparison, but the team should verify the specific delivery, access, and operations terms before treating any resource as a production Runner.
A locally owned Mac can offer direct control and physical access, but the team carries procurement, replacement, and maintenance work. A remote Mac can avoid keeping another machine in the office, but it still requires documented access controls, recovery ownership, network review, and a tested CI handoff. A generic virtual or non-Mac host may suit many build tasks, but it cannot substitute for Mac-specific toolchain requirements. We would choose based on workload, security controls, and recovery evidence—not on an Online indicator alone.
If the current problem is that an unattended Mac cannot be restored remotely after a restart, compare the recovery steps above with the actual operating and access terms of the proposed hosting option. MESHLAUNCH may be worth evaluating when the team needs a temporary or adjustable Mac CI environment; teams with sustained, predictable workloads or a need for physical interfaces should also assess owning and operating dedicated hardware. Resume production only when the selected path passes the same job-routing and pipeline acceptance checks.