> For the complete documentation index, see [llms.txt](https://docs.spacecoin.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.spacecoin.org/spacerouter-onion/troubleshooting.md).

# Troubleshooting

A short guide to the most common issues when running the SpaceRouter Onion proxy from the command line. If you are using the SpaceRouter Onion App or the browser extension, most of these conditions surface as a red indicator or a notification; the same root causes apply.

***

### Proxy won't start

Symptoms: the process exits immediately, or hangs at startup, or prints an error about listeners.

#### Port is already in use

The SOCKS5 and HTTP API listeners default to `127.0.0.1:1080` and `127.0.0.1:2080`. If either port is already bound, the proxy fails with an "address already in use" error.

Check what is using the ports:

{% tabs %}
{% tab title="macOS / Linux" %}

```bash
lsof -iTCP:1080 -sTCP:LISTEN -n -P
lsof -iTCP:2080 -sTCP:LISTEN -n -P
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```ps
Get-NetTCPConnection -LocalPort 1080
Get-NetTCPConnection -LocalPort 2080
```

{% endtab %}
{% endtabs %}

If the output shows another process, either stop that process or move the SpaceRouter Onion proxy onto different ports with `--listen` and `--api-listen`.

#### Data directory is not writable

The proxy persists `proxy-prefs.json` and `.guardstate` inside `--data-dir`. If the directory does not exist or the user running the proxy cannot write to it, startup fails.

{% tabs %}
{% tab title="macOS" %}

```bash
# Make sure the directory exists and is owned by the proxy user
sudo mkdir -p ~/Library/Application Support/SpaceRouter Onion/
sudo chown spacerouter:spacerouter ~/Library/Application Support/SpaceRouter Onion/
```

{% endtab %}

{% tab title="Linux" %}

```shellscript
# Make sure the directory exists and is owned by the proxy user
sudo mkdir -p ~/.local/share/SpaceRouter Onion/
sudo chown spacerouter:spacerouter ~/.local/share/SpaceRouter Onion/
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
# Make sure the directory exists and is owned by the current user
$dir = "$env:%APPDATA%\SpaceRouter Onion\"
New-Item -ItemType Directory -Force -Path $dir

$acl = Get-Acl $dir
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "spacerouter",
    "FullControl",
    "ContainerInherit,ObjectInherit",
    "None",
    "Allow"
)
$acl.SetAccessRule($rule)
Set-Acl -Path $dir -AclObject $acl
```

{% endtab %}
{% endtabs %}

#### Discovery source is unreachable at startup

With `--auto-start <network-id>` the proxy resolves discovery before it will accept traffic. If the discovery URL or contract returns nothing, times out, or the file path does not exist, the proxy logs the error and never enters the "enabled" state. Drop `--auto-start` to let the proxy start its listeners even when discovery is offline, then fix discovery and trigger `POST /api/start`.

***

### Can't reach `/api/status`

Symptoms: the extension shows "proxy unreachable", `curl http://127.0.0.1:2080/api/status` times out or returns a connection-refused error.

#### The proxy process isn't running

First, confirm the process is alive:

{% tabs %}
{% tab title="macOS / Linux" %}

```shell
pgrep -af proxy
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
Get-Process proxy
```

{% endtab %}
{% endtabs %}

If nothing is running, start it directly in a terminal (not as a service) and watch the output. Startup errors almost always explain themselves in the first few log lines.

#### The API is bound to a different address

The extension and the desktop app assume `http://127.0.0.1:2080`. If you launched the proxy with a different `--api-listen`, the clients will not reach it. Either restart the proxy with the default address, or update the "Proxy API URL" field in the extension's configuration view / the desktop app's settings.

#### Firewall is blocking localhost (rare but real)

Corporate machines sometimes ship with firewall profiles that block loopback connections to non-standard ports. Temporarily permit `127.0.0.1:2080` in the firewall or relocate the proxy to a port your environment allows.

#### The listener is bound to a specific interface

A `--api-listen 192.168.1.10:2080` bind will not accept connections on `127.0.0.1`. Use `--api-listen 0.0.0.0:2080` if you intentionally want to reach the proxy from another host on the LAN; otherwise keep the default loopback bind.

***

### Circuit build fails

Symptoms: `POST /api/start` returns a 500, logs mention "failed to build circuit", the extension popup spins on "Starting…" and then reports an error.

#### Discovery returned zero nodes

A circuit needs at least `--hops` distinct nodes, with at least one of them flagged as an exit. If discovery returns fewer than that (or returns an empty list), every build attempt fails.

{% tabs %}
{% tab title="macOS / Linux" %}

```shell
curl -s http://127.0.0.1:2080/api/nodes | jq '.nodes | length'
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
(Invoke-RestMethod -Uri "http://127.0.0.1:2080/api/nodes").nodes.Count
```

{% endtab %}
{% endtabs %}

#### No exit-capable nodes in the set

An exit node is any node whose `flags` field has the exit bit set. If no node in the returned list is exit-capable, the proxy cannot complete the circuit. Confirm the network you selected (`--network-id`) actually contains exit nodes and that you are not restricting the pool to an unusable subset.

#### Handshake timeout against the guard

Log lines like `session handshake timed out after 15s` usually mean one of:

* The guard node is offline or has been taken out of rotation but is still in the cached node list. Wait for the next discovery refresh (three minutes) or force a new guard with `curl -X POST http://127.0.0.1:2080/api/guard/rotate` while the proxy is stopped.
* A firewall is dropping the QUIC UDP handshake on the path.&#x20;

***

### Collecting logs for a bug report

If you can't fix the issue yourself and want to open an issue on GitHub, the most useful attachments are the proxy's own logs captured at a higher verbosity.

#### What to include in the report

{% tabs %}
{% tab title="macOS / Linux" %}

1. The exact command (or service configuration) you started the proxy with, redacting any private discovery URLs.
2. The output of `curl -s http://127.0.0.1:2080/api/status | jq .` captured immediately before the failure.
3. The last 200 to 500 lines of the log file, from the first error back through the handshake or circuit-build attempt that failed.
4. The version of the binary: `proxy version`.
5. Your platform (`uname -a` on macOS/Linux, `winver` on Windows).
   {% endtab %}

{% tab title="Windows (Powershell)" %}

1. The exact command (or service configuration) you started the proxy with, redacting any private discovery URLs.
2. The output of `Invoke-RestMethod -Uri "http://127.0.0.1:2080/api/status"` captured immediately before the failure.
3. The last 200 to 500 lines of the log file, from the first error back through the handshake or circuit-build attempt that failed.
4. The version of the binary: `proxy version`.
5. Your platform ( `winver` ).
   {% endtab %}
   {% endtabs %}

#### What not to include

The default logs do not contain packet payload. Avoid using `--sensitive-log`; it was built for protocol debugging on a single private machine and records cleartext traffic. Never attach a sensitive-log file to a public issue tracker.
