Skip to main content

Troubleshooting

Common issues and how to resolve them when deploying the Tunnel Agent.

How routing works

Understanding the request flow helps diagnose issues:

Zihin Cloud sends a request to:
tunnel.zihin.ai/t/{tenant_id}/{service}/{path...}
────────── ──────── ─────────
1. identifies 2. service 3. forwarded
the tunnel name to the agent

Agent receives: { service: "my-service", path: "/api/data" }
Agent resolves: "my-service" → base URL from config
Agent fetches: GET https://internal-host:8080/api/data

The path from the cloud endpoint is appended to the base URL configured in the agent. The agent only provides host and port — the path comes from the request.

Error reference

404 — "No tunnel found for tenant"

The agent is not connected to the tunnel server.

Possible causeSolution
Token (ztun_...) is incorrect or expiredVerify ZIHIN_TOKEN environment variable, request a new token
Agent is not runningCheck with docker ps or systemctl status
Firewall blocking outbound WSS on port 443Allow outbound HTTPS/WSS to tunnel.zihin.ai

401 — "Unauthorized"

Two possible sources — check the response body to distinguish:

SourceResponse bodyAgent logsCause
Tunnel Server{"error":"Unauthorized"}No log (request doesn't reach agent)Invalid or missing Bearer token
Internal serviceHTML or JSON from the serviceFetch completed { status: 401 }Service credential (xc-mcp-token, etc.) is invalid

If the response body is {"error":"Unauthorized"}, the issue is at the Tunnel Server level — verify that the cloud service is sending the correct Authorization: Bearer header.

502 — "Bad gateway"

The agent is connected, but the local fetch to the internal service failed.

Possible causeSolution
Internal service URL is unreachable from the containerTest connectivity from inside the container (see below)
Self-signed SSL certificate without treatmentAdd ssl_verify: false or mount the CA certificate
Wrong port for the internal serviceVerify the correct port
Internal service rejected the authentication tokenTest the token directly with curl from the server

Diagnosis: Set log_level: debug in the agent config. The log line Fetch failed { code, error } shows the exact error.

504 — "Gateway timeout"

The internal service took longer than 30 seconds to respond.

  • Check the health of the internal service
  • Avoid large queries without filters or pagination

SERVICE_NOT_FOUND

The service name in the agent config doesn't match the request.

The service name in zihin-agent.yml must match the {service} segment in the cloud endpoint URL:

Cloud endpoint: /t/{tenant}/nocodb/mcp/...
──────
Agent config: services:
- name: nocodb ← must match

Authentication errors (4001, 4003)

CodeMeaningSolution
4001Invalid or expired tokenCheck ZIHIN_TOKEN, request a new token
4003Tunnel not found on the serverContact the Zihin team to verify provisioning

Diagnostic commands

Test from inside the Docker container

If the agent returns 502, test whether the container can reach the internal service:

# Test basic connectivity
docker exec zihin-tunnel wget -qO- --no-check-certificate https://INTERNAL_HOST:PORT/

# If this fails, the container can't reach the service.
# Solution: add network_mode: host to docker-compose.yml

Test the internal service directly (from SSH)

# Test the service endpoint with authentication
curl -sk -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
https://INTERNAL_HOST:PORT/api/endpoint

Enable debug logs

# In zihin-agent.yml
log_level: debug

Or via environment variable:

export ZIHIN_LOG_LEVEL=debug

Restart the agent after changing the log level. Remember to set it back to info after troubleshooting.

Common issues

SymptomLikely causeSolution
Reconnect loopFirewall blocking outbound 443Allow outbound HTTPS/WSS to tunnel.zihin.ai
Agent token is requiredZIHIN_TOKEN not setSet the environment variable before starting
No services definedYAML missing services blockAdd at least one service to zihin-agent.yml
HOST_NOT_ALLOWEDHost policy restricts accessContact the Zihin team to adjust allowed_hosts
RATE_LIMITEDToo many requests per minuteReduce request frequency or request a limit increase
Response timeoutInternal service slow or unreachableVerify the service URL is accessible from the agent machine

HTTP status codes — quick reference

HTTPMeaningWhere it failed
200Success
401Invalid Bearer token or service credentialCloud → Tunnel Server (check response body for {"error":"Unauthorized"}) or Agent → Internal service
404Agent offline or tunnel doesn't existTunnel Server
429Rate limit exceededTunnel Server or Agent
502Agent connected, local fetch failedAgent → Internal service
504Timeout (>30s)Agent → Internal service

Support

If you need help:

  • Send logs with debug level to the Zihin team
  • Include the agent version: docker exec zihin-tunnel node dist/index.js --version
  • Describe your setup: number of services, network type, corporate proxy (if any)