> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.proto.xyz/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.proto.xyz/_mcp/server.

# Troubleshoot a Fleet Node

Start with the installed version, systemd service, and recent logs:

```bash
cat /opt/fleetnode/version.txt
sudo systemctl status fleet-node.service --no-pager
sudo journalctl -u fleet-node.service -n 200 --no-pager
```

To inspect the stored connection without printing credentials:

```bash
sudo runuser -u fleetnode -- \
  /opt/fleetnode/fleetnode --state-dir /var/lib/fleetnode status
```

The status command prints the Fleet server URL, node ID, identity fingerprint, whether an API key and session token are present, and the session expiry. It does not print the credentials.

## Read the status in Fleet

Open **Settings → Nodes**.

| Status                        | Meaning                                                                               |
| ----------------------------- | ------------------------------------------------------------------------------------- |
| **Online**                    | Fleet received a heartbeat within the last two minutes.                               |
| **Stale**                     | The node previously connected but has not sent a heartbeat for more than two minutes. |
| **Never connected**           | Enrollment was confirmed, but Fleet has not received a heartbeat.                     |
| **Awaiting confirmation**     | The host registered and is waiting for fingerprint confirmation.                      |
| **Online - upgrade required** | The node is connected but does not support the command protocol required by Fleet.    |
| **Revoked**                   | The node no longer has access to Fleet.                                               |

## Resume an interrupted enrollment

Run the same command shown by **Settings → Nodes → Enroll node**:

```bash
sudo fleetnode-enroll --server-url=https://fleet.example.com/api-proxy
```

If the host registered but did not receive its API key, the helper resumes the authentication prompt. In Fleet, use **Confirm enrollment** for the waiting node, compare the fingerprint, and paste the new API key into the host prompt.

If the one-time enrollment code expired before registration, close the enrollment window and start again to create a new code.

## The node is stale or never connected

1. Check `fleet-node.service` and its recent logs.
2. Confirm that the Fleet Node host can resolve and reach the stored `server_url`.
3. Confirm that the host clock is correct. Authentication challenges expire.
4. Confirm that the node has not been revoked in Fleet.
5. If Fleet uses a private certificate authority, confirm that the Fleet Node host trusts it.

Restart the service after correcting the problem:

```bash
sudo systemctl restart fleet-node.service
```

## The certificate is not trusted

Fleet Node verifies HTTPS certificates with the host's trust store. Install the certificate authority that issued Fleet's certificate, then restart the service.

For a high-availability Fleet deployment, first compare the public service CA fingerprint with the authenticated installer output. Then install the verified certificate on a Debian-based Fleet Node host:

```bash
sudo install -m 0644 proto-fleet-ha-service-ca.crt \
  /usr/local/share/ca-certificates/proto-fleet-ha-service-ca.crt
sudo update-ca-certificates
sudo systemctl restart fleet-node.service
```

Do not use `--allow-insecure-transport` to bypass an HTTPS certificate problem. That option permits HTTP for testing; it does not turn off HTTPS certificate verification.

## Miners are not discovered

Confirm that the Fleet Node host can route to each scan target and reach the discovery ports listed under [supported hardware](/fleet/home#supported-hardware).

Automatic local discovery chooses a private IPv4 subnet from the host. On a host with multiple network interfaces, set the intended subnet in `/etc/fleetnode/fleetnode.env`:

```bash
sudoedit /etc/fleetnode/fleetnode.env
```

Add one line with a private IPv4 CIDR:

```text
FLEETNODE_LOCAL_DISCOVERY_SUBNET=10.90.0.0/24
```

Then restart the node:

```bash
sudo systemctl restart fleet-node.service
```

The subnet must be private and within Fleet's supported scan-size limit. You can also enter explicit private IP addresses or smaller subnets when starting discovery in Fleet.

## Re-enroll with a different Fleet server

Changing the server discards the host's existing node identity.

1. In the old Fleet deployment, revoke the node under **Settings → Nodes**.
2. In the new Fleet deployment, start **Enroll node** and copy its command and one-time code.
3. On the host, run the copied command with `--force` appended.
4. Compare the new identity fingerprint before confirming the node.

The helper stops the service before replacing local enrollment state.

## An update does not complete

* If the installer reports a download or checksum problem, the installed service has not been replaced. Confirm outbound HTTPS access and retry the same exact release.
* If it reports that another installer is running, wait for that process to finish before retrying.
* If the service is `activating`, inspect its logs. The installer will not replace a service during an incomplete start.
* If the candidate cannot start, review both the candidate error and any rollback message. A successful rollback restores and restarts the previous service.

For help interpreting the output, open a [GitHub Discussion](https://github.com/block/proto-fleet/discussions) or [report a bug](/fleet/support#report-a-bug-or-request-a-feature). Do not attach `/var/lib/fleetnode/state.yaml`, API keys, enrollment codes, or private keys.