For the complete documentation index, see llms.txt. This page is also available as Markdown.

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:

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

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.

# 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/

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:

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.

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.


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

  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).

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.

Last updated

Was this helpful?