openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
214 lines (166 loc) • 12.6 kB
Markdown
---
summary: "Troubleshoot node pairing, foreground requirements, permissions, and tool failures"
read_when:
- Node is connected but camera/screen/exec tools fail
- You need the node pairing versus approvals mental model
title: "Node troubleshooting"
---
Use this page when a node is visible in status but node tools fail.
## Node goes offline after SSH logout (Linux)
On Linux, `openclaw node install` creates a **user-level** systemd service. The
`systemd --user` instance is torn down when your last login session ends, so the
node service stops the moment you log out — even though it looked healthy
(`enabled` + `running`) while you were connected.
Check lingering:
```bash
loginctl show-user "$USER" -p Linger
```
If it reads `Linger=no`, enable it (may require sudo):
```bash
sudo loginctl enable-linger "$USER"
```
Then restart the node service and verify it survives logout:
```bash
openclaw node restart
# log out, then from another machine:
openclaw nodes status
```
`openclaw node install` prints a warning with this recovery command when it
detects lingering is disabled. Don't mix a user-level service with a
system-level one for the same node. The duplicate-scope guard that prevents
two managers from running the same unit name is enforced for gateway units
(two supervisors on the same port SIGTERM each other in a restart loop); for
node services the installer does not raise this guard, so a leftover unit in
the other scope can leave the node in an ambiguous state. Fully remove one
before switching.
## Command ladder
```bash
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
```
Then run node-specific checks:
```bash
openclaw nodes pending
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
openclaw approvals get --node <idOrNameOrIp>
```
Healthy signals:
- Node is connected and paired for role `node`.
- `nodes describe` includes the capability you're calling.
- Exec approvals show the expected mode/allowlist.
If startup preparation disables container session hosting that you enabled, check the node host's
local stderr for `node host worker hosting disabled: ...` and follow the reported
engine or context recovery guidance. The macOS app forwards worker stderr to its
logger under subsystem `ai.openclaw`, category `node-host-worker`; see
[macOS logging](/platforms/mac/logging) for capture options. After fixing the cause,
restart the node host. Explicitly disabled hosting produces no such diagnostic.
After a node-host restart, session capacity remains occupied until worker cleanup
is verified. On Linux and macOS, released direct workers are recovered through
their original process group even if its leader has already exited. Newer workers
retain a cleanup anchor that records descendant completion before exiting; recovery also waits for its
process group to disappear. If the anchor dies without that record, the node logs
`lost its cleanup anchor without recorded lineage completion` and keeps the slot
reserved. Inspect remaining worker descendants and the node-host logs; another
restart alone cannot establish that cleanup finished. Other free slots remain
available. See the [database compatibility contract](/reference/database-schemas/versioning)
before downgrading a node with active workers.
If a Windows node host exits before confirming worker cleanup, its unfinished
claims and slots stay reserved across restarts. Losing or reusing a worker's PID
does not prove that its descendants stopped. Cleanup confirmed by the original
host still releases capacity normally; container-isolated workers on supported
hosts use their container engine's removal confirmation.
## Node runtime version differs from the CLI
A packaged headless node can run a newer private runtime than the globally
installed CLI. Use `openclaw nodes status --json` to check the connected node's
version; `openclaw --version` reports the CLI version. For delayed updates,
opt-outs, fallback, and migration or repair deferrals, see
[Headless node updates](/install/updating/automatic-updates#headless-node-updates).
If an apparently idle node keeps deferring an update, check its installed
plugins. A plugin without an idle-work callback cannot confirm that its
background work has finished, so the node keeps running. Update the plugin, or
finish its work before updating and restarting the node manually.
## Foreground requirements
`camera.*` and `screen.*` are foreground-only on iOS/Android nodes.
Quick check and fix:
```bash
openclaw nodes describe --node <idOrNameOrIp>
openclaw logs --follow
```
If you see `NODE_BACKGROUND_UNAVAILABLE`, bring the node app to the foreground and retry.
## Permissions matrix
| Capability | iOS | Android | macOS node app | Typical failure code |
| ---------------------------- | --------------------------------------- | -------------------------------------------- | -------------------------------- | --------------------------------------------- |
| `camera.snap`, `camera.clip` | Camera (+ mic for clip audio) | Camera (+ mic for clip audio) | Camera (+ mic for clip audio) | `*_PERMISSION_REQUIRED` |
| `screen.record` | Screen Recording (+ mic optional) | Screen capture prompt (+ mic optional) | Screen Recording | `*_PERMISSION_REQUIRED` |
| `computer.act` | n/a | n/a | Accessibility + Screen Recording | `COMPUTER_DISABLED`, `ACCESSIBILITY_REQUIRED` |
| `location.get` | While Using or Always (depends on mode) | Foreground/Background location based on mode | Location permission | `LOCATION_PERMISSION_REQUIRED` |
| `system.run` | n/a (node host path) | n/a (node host path) | Exec approvals required | `SYSTEM_RUN_DENIED` |
## Pairing versus approvals
Four separate approval and policy gates control whether a node command succeeds:
1. **Device pairing**: can this node connect to the gateway?
2. **Node command surface approval**: has the declared command been approved through `openclaw nodes pending` and `openclaw nodes approve <nodeRequestId>`?
3. **Gateway node command policy**: is the RPC command ID allowed by `gateway.nodes.commands.allow` / `gateway.nodes.commands.deny` and platform defaults?
4. **Exec approvals**: can this node run a specific shell command locally?
Device pairing admits the identity; surface approval limits the commands on its
paired-device record. The two request IDs are distinct. An initial unapproved
surface exposes no effective commands. A pending expansion retains only commands
that were already approved, remain declared, and pass Gateway policy. For
`system.run`, shell allowlist and ask policy live in the node's exec approvals
(`openclaw approvals get --node ...`), not the pairing record. Platform permissions
and foreground requirements still apply.
Quick checks:
```bash
openclaw devices list
openclaw nodes pending
openclaw nodes status
openclaw approvals get --node <idOrNameOrIp>
openclaw approvals allowlist add --node <idOrNameOrIp> "/usr/bin/uname"
```
- Pairing missing: approve the current device request with `openclaw devices approve <deviceRequestId>`, then restart or rerun a node paused on `PAIRING_REQUIRED`. The reconnect creates the separate surface request.
- Node paired and connected with an initial empty command list: inspect `openclaw nodes pending` and approve its distinct `<nodeRequestId>` with `openclaw nodes approve <nodeRequestId>`.
- `nodes describe` missing a command: check the gateway node command policy and whether the node actually declared that command on connect.
- Surface approved but `system.run` fails: check Gateway policy, then exec approvals/allowlist on that node.
SSH-verified and bootstrap enrollment can approve the first surface automatically.
Trusted-network device approval does not. Later command, capability, or permission
expansion still needs surface approval.
For approval-backed `host=node` runs, the gateway also binds execution to the prepared canonical `systemRunPlan`. If a later caller mutates the command, cwd, or session metadata before the approved run is forwarded, the gateway rejects the run as an approval mismatch instead of trusting the edited payload.
## Common node error codes
| Code | Meaning |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NODE_BACKGROUND_UNAVAILABLE` | App is backgrounded; bring it to the foreground. |
| `CAMERA_DISABLED` | Camera toggle disabled in node settings. |
| `*_PERMISSION_REQUIRED` | OS permission missing/denied. |
| `LOCATION_DISABLED` | Location mode is off. |
| `LOCATION_PERMISSION_REQUIRED` | Requested location mode not granted. |
| `LOCATION_BACKGROUND_UNAVAILABLE` | App is backgrounded but only While Using permission exists. |
| `COMPUTER_DISABLED` | Enable **Allow Computer Control** in the macOS app, then approve the pairing update. |
| `ACCESSIBILITY_REQUIRED` | Grant Accessibility to the current OpenClaw app bundle in macOS System Settings. |
| `SYSTEM_RUN_DENIED: approval required` | Exec request needs explicit approval. |
| `SYSTEM_RUN_DENIED: allowlist miss` | Command blocked by allowlist mode. On Windows node hosts, shell-wrapper forms like `cmd.exe /c ...` are treated as allowlist misses in allowlist mode unless approved via the ask flow. |
## Fast recovery loop
```bash
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
openclaw approvals get --node <idOrNameOrIp>
openclaw logs --follow
```
If still stuck:
- Re-approve device pairing.
- Restart or rerun a node paused for manual pairing, then approve its pending surface request with `openclaw nodes pending` / `openclaw nodes approve <nodeRequestId>`.
- Re-open the node app (foreground).
- Re-grant OS permissions.
- Recreate/adjust the exec approval policy.
For computer control, also verify that the node-local Computer Control toggle is enabled, its pairing update is approved, a vision-capable agent exposes the `computer` tool, and `screen.snapshot` succeeds with Screen Recording permission. A `gateway.nodes.commands.deny` entry always overrides a platform default or `gateway.nodes.commands.allow`.
## Related
- [Nodes overview](/nodes)
- [Camera nodes](/nodes/camera)
- [Location command](/nodes/location-command)
- [Computer use](/nodes/computer-use)
- [Exec approvals](/tools/exec-approvals)
- [Gateway pairing](/gateway/pairing)
- [Gateway troubleshooting](/gateway/troubleshooting)
- [Channel troubleshooting](/channels/troubleshooting)