Troubleshoot 9Router connection and model errors
Diagnose 9Router connection, authentication, model, quota, proxy, and streaming failures. Identify the failing layer before changing your client configuration.
Find the first failing boundary before changing your configuration. A request travels from the client to 9Router, then from 9Router to a provider. Test those boundaries separately. Reinstalling the client or adding more fallback models often leaves the original error untouched.
Keep the exact HTTP status and a redacted error message. Record the client version, router version, model ID, and whether the deployment uses npm or Docker. Never include API keys, cookies, authorization headers, private prompts, or a complete unredacted configuration file in a public report.
Choose the symptom
| Symptom | First check | Next step |
|---|---|---|
| Connection refused | Is the router process listening on the expected port? | Check startup logs and host address |
| Dashboard opens, API fails | Is the client using the API base path? | Inspect endpoint and router authentication |
| 401 or 403 | Which service rejected the request? | Separate router credentials from provider credentials |
| Model not found | What exact model string did the router receive? | Correct the provider prefix or combo mapping |
| 429 | Which provider or router limit applies? | Read the error body and documented quota |
| Timeout | Where does the request stop? | Check host, proxy, provider, and streaming in that order |
| Text works, tool use fails | Does the model and translation path support tools? | Reproduce with a small scratch task |
1. Confirm the local server
From the same environment that runs the client, request the health endpoint:
curl -i http://localhost:20128/api/health
If the connection is refused, confirm that the router is running. For Docker, check container state and recent logs:
docker ps --filter name=9router
docker logs --tail 100 9router
Look for a port conflict, failed startup, or data-directory permissions. Do not delete the data folder as a first response. Back it up while the router is stopped before attempting a repair that could change stored settings.
If the browser can open the dashboard but the client cannot reach the server, compare their environments. A browser on your host and a client inside a container do not share the same meaning of localhost.
2. Confirm the API path
The reviewed client writers normalize their base URL to end in /v1. Use the URL generated for your installed client integration. A dashboard URL is not necessarily an API endpoint, and appending /v1 twice can produce an incorrect route.
Inspect the request path without logging the authorization header. Codex’s current setup uses the Responses API. A chat-completions route is not a substitute merely because both APIs accept text.
A 404 is especially useful here: it often points to a path or capability mismatch. Determine which server returned the 404 before changing the model.
3. Separate two authentication boundaries
Your client may use a router key to access 9Router. The router then uses a different credential to access a provider. A dashboard password is another credential with a different purpose.
For a 401 or 403, inspect the redacted error body and router log to locate the rejection. If the router rejects the client, verify the router key and whether API authentication is enabled. If the upstream service rejects the router, check that provider connection’s status and supported authentication method.
Restart the client after changing persistent settings. An existing process may keep earlier environment values. Also check whether a profile or project-level setting overrides the file you edited.
4. Check model IDs and aliases
Copy an exact model ID from the running dashboard or API list. Preserve its provider prefix. A friendly display label, client alias, and combo name may look similar while identifying different things.
Test a direct model before a combo. If the direct model works but the combo fails, inspect the combo’s entries and routing strategy. If neither works, the combo is unlikely to be the first problem to solve.
A listed model can still be unavailable to your account. Model discovery and successful inference are separate checks.
5. Read 429 responses carefully
A 429 means a limit was applied, but it does not identify that limit by itself. It may involve provider usage, request rate, account entitlement, or a configured router constraint.
An upstream report from 22 October 2026 includes an OpenCode FreeUsageLimitError. Treat the report as a reproducible symptom to investigate, not proof of the theories in its comments. Check the provider’s current documented policy and your actual account state.
Respect any supplied retry timing. Avoid a tight retry loop, which can increase load and obscure the original response. If the selected route is unavailable, use an authorized alternative whose limits and costs you understand.
6. Isolate a proxy timeout
Another upstream report describes SOCKS5 connection timeout when testing a configured proxy pool. The report does not contain a verified universal fix.
Check the proxy host, port, supported protocol, and authentication with your proxy service’s documentation. Test reachability from the router’s host, not only from your laptop browser. A container may have different network access.
If the proxy is optional and policy allows a direct connection, compare one direct test in a separate configuration. Do not silently bypass an organizational network requirement. Change one setting at a time and preserve the previous value.
7. Test streaming and tools separately
A short text reply does not verify a long coding session. Reproduce a streaming or tool failure with a small scratch task and one model. Compare the client error with the router request status.
If the provider completes a response but the client hangs, inspect translation, streaming termination, and any reverse proxy buffering. If the provider itself never completes, investigate that route before changing the client.
For an upstream issue, provide redacted reproduction steps, versions, expected behavior, actual status, and whether a direct model or combo was used. Describe what you actually tested. That gives maintainers more to work with than a screenshot saying “doesn’t work.”
References for this guide
- Upstream troubleshooting documentation
- Upstream Docker health and data instructions
- SOCKS5 connection timeout report
- OpenCode free-usage error report
Steps were checked against the linked documentation and source. Provider access and model availability depend on your account. We do not claim a completed live model test unless explicitly stated.