Troubleshooting
Common issues when running the Tunnel Agent and how to resolve them.
Error reference
| HTTP | Response body / symptom | Cause | What to do |
|---|---|---|---|
| 404 | {"error":"No tunnel found for tenant"} | Agent not connected | Check the agent is running, ZIHIN_TOKEN is correct, and outbound 443 to tunnel.zihin.ai is allowed |
| 404 | {"error":"Service not found on tunnel: ..."} | Agent connected, but no service with that name | The services[].name in zihin-agent.yml must match the {service} segment of the endpoint configured in Zihin Cloud |
| 401 | {"error":"Unauthorized"} (no agent log) | Zihin side: invalid Bearer to the tunnel server | Contact the Zihin team |
| 401 | Body from your service; agent logs status: 401 | Credential in inject_headers rejected by the internal service | Fix the token/API key in inject_headers and restart |
| 406 | Not Acceptable (MCP services) | An Accept header in inject_headers overrides the one the MCP client sends | Remove Accept from inject_headers and restart |
| 502 | Bad gateway | Agent connected, but the local request to the internal service failed (URL, port, TLS, network) | Set log_level: debug; the line Fetch failed { code, error } shows the cause. See diagnostics below |
| 503 | Too many concurrent streams | Too many simultaneous streaming (SSE) connections | Close unused streams or contact the Zihin team |
| 504 | Gateway timeout | The internal service took longer than 120s to respond | Check the health of the internal service; avoid unfiltered queries |
Connection codes (agent logs)
| Code | Meaning | What to do |
|---|---|---|
4001 | Invalid or expired token | Check ZIHIN_TOKEN; rotate the token in the Console if needed |
4002 | Connection limit for your tunnel reached | Harmless — the extra connection waits and retries. To use more, lower pool_size or ask the Zihin team to raise the limit |
4003 | Tunnel not found | Contact the Zihin team to verify provisioning |
Other messages
| Message | Cause | What to do |
|---|---|---|
| Reconnect loop | Outbound 443 blocked | Allow outbound HTTPS/WSS to tunnel.zihin.ai |
Agent token is required | ZIHIN_TOKEN not set | Set the variable before starting |
No services defined | YAML missing services | Add at least one service |
HOST_NOT_ALLOWED | Host policy restricts access | Contact the Zihin team |
RATE_LIMITED | Too many requests per minute | Reduce frequency or request a limit increase |
Diagnostics
Test from inside the container (for 502):
docker exec zihin-tunnel wget -qO- --no-check-certificate https://INTERNAL_HOST:PORT/
# If this fails, the container can't reach the service — try network_mode: host in docker-compose.yml
Test the internal service directly (from the host):
curl -sk -H "Authorization: Bearer YOUR_TOKEN" https://INTERNAL_HOST:PORT/api/endpoint
Enable debug logs — set log_level: debug in zihin-agent.yml (or ZIHIN_LOG_LEVEL=debug) and restart. Set it back to info afterwards.
Agent version:
docker exec zihin-tunnel node dist/index.js --version
Support
When contacting the Zihin team, include:
- Agent logs at
debuglevel - The
X-Tunnel-Request-Idresponse header of a failing request (every tunnel response carries one) - The agent version and a short description of your setup (services, network, corporate proxy)