XX-net/XX-Net · warning · XTunnelNotRunning
XTunnelNotRunning
Error message
XTunnelNotRunning
What it means
do_socks raises XTunnelNotRunning when the X-Tunnel proxy is unavailable. This first site fires when accessing g.x_tunnel.proxy_session fails or is unset — i.e. the X-Tunnel subsystem was never started or has already shut down, so attribute access on None raises and the except converts it to XTunnelNotRunning, letting try_loop fall back to another route.
Source
Thrown at code/default/smart_router/local/smart_route.py:249
xlog.debug("host:%s:%d redirect_https connect %s success", host, port, remote_sock.ip)
if left_buf:
ssl_sock.send(left_buf)
sw = SocketWrap(ssl_sock, remote_sock.ip, port, host)
sock.recved_times = 3
g.pipe_socks.add_socks(sock, sw)
def do_socks(sock, host, port, client_address, left_buf=b""):
if not g.x_tunnel:
raise XTunnelNotRunning()
try:
conn_id = g.x_tunnel.proxy_session.create_conn(sock, host, port, True)
except Exception as e:
xlog.warn("do_sock to %s:%d, x_tunnel fail:%r", host, port, e)
raise XTunnelNotRunning()
if not conn_id:
xlog.warn("x_tunnel create conn fail")
raise XTunnelNotRunning()
# xlog.debug("do_socks %r connect to %s:%d conn_id:%d", client_address, host, port, conn_id)
if left_buf:
g.x_tunnel.global_var.session.conn_list[conn_id].transfer_received_data(left_buf)
g.x_tunnel.global_var.session.conn_list[conn_id].start(block=True)
def do_unwrap_socks(sock, host, port, client_address, req, left_buf=b""):
if not g.x_tunnel:
return
try:
remote_sock = socks.create_connection(
(host, port),View on GitHub (pinned to cfa5bc17b6)
Solutions
- Ensure X-Tunnel is enabled and logged in so g.x_tunnel.proxy_session exists before traffic is routed to it
- Check X-Tunnel login status/log for the root cause of the tunnel not running
- Adjust smart_router rules or goagent config so socks traffic prefers a working strategy (direct/GAE) when tunnel is down
- Catch XTunnelNotRunning in try_loop to fall back to the next route (this is the designed behavior)
Example fix
// conceptual
# before
conn_id = g.x_tunnel.proxy_session.create_conn(sock, host, port, True)
# after
if not g.x_tunnel or not getattr(g.x_tunnel, 'proxy_session', None):
raise XTunnelNotRunning() # explicit check instead of relying on AttributeError Defensive patterns
Strategy: type-guard
Validate before calling
def x_tunnel_ready():
return bool(getattr(g, 'x_tunnel', None) and getattr(g.x_tunnel, 'proxy_session', None)) Type guard
def x_tunnel_ready() -> bool:
xt = getattr(g, 'x_tunnel', None)
return xt is not None and getattr(xt, 'proxy_session', None) is not None Try / catch
try:
do_socks(...)
except XTunnelNotRunning:
try_next_strategy(sock, host, port) Prevention
- Check g.x_tunnel/proxy_session before adding X-Tunnel to rule_list
- Monitor tunnel login state and remove the strategy when down
When it happens
Trigger: A SOCKS connection is routed to the X-Tunnel strategy while g.x_tunnel is None (X-Tunnel not logged in / not enabled), or proxy_session is missing because the tunnel stopped.
Common situations: X-Tunnel account not configured or login failed at startup, tunnel service shut down mid-run, deployment where only GAE proxy is enabled but routing rules still send traffic to X-Tunnel.
Related errors
- %s file format error
- DontFakeCA
- ConnectionPipe remove sock e:%r
- proxy handler read error %r
- login session server is down, try get new server.
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/2032a4c1ba08ad7e.
Report an issue: GitHub.