XX-net/XX-Net · error
roundtrip failed, no:%d target:%d on_road:%d timeout:%d send
Error message
roundtrip failed, no:%d target:%d on_road:%d timeout:%d send:%d
What it means
Emitted when a roundtrip_task exhausts its retry/timeout loop without receiving the expected transfer (transfer_no) from the server. It reports the transfer number, target vs actual on-road requests, the server timeout and the size of the upload data, then notifies the wait queue so waiting workers can proceed. Functionally it means the upload/download multiplexed transfer failed for this round.
Source
Thrown at code/default/x_tunnel/local/proxy_session.py:1098
del self.transfer_list[transfer_no]
self.round_trip_process(data, ack, rcvd_no_list, sent_no_list, unack_snd_sn, server_time)
self.check_upload_not_acked(server_time)
if self.on_road_num + 1 < self.target_on_roads:
self.wait_queue.notify()
self.wait_queue.notify()
return
except Exception as e:
xlog.exception("trip:%d no:%d data not enough %r", work_id, transfer_no, e)
data_info["stat"] = "timeout"
continue
# xlog.debug("trip:%d no:%d recv data:%s", work_id, transfer_no, parse_data(data))
xlog.warn("roundtrip failed, no:%d target:%d on_road:%d timeout:%d send:%d",
transfer_no, self.target_on_roads, self.on_road_num, server_timeout,
len(upload_post_data))
self.wait_queue.notify()
def parse_data(data):
if len(data) == 0:
return ""
o = ""
data = bytes(data)
data = base_container.ReadBuffer(data)
while len(data):
sn, block_len = struct.unpack("<II", data.get(8))
block = data.get_buf(block_len)
View on GitHub (pinned to cfa5bc17b6)
Solutions
- Verify connectivity and re-login: call/trigger request_balance and confirm quota > 0 and session is alive.
- Check server availability and switch g.server_host to another relay.
- Retry the roundtrip (the waiters are notified; a new roundtrip_task will be spawned) and watch for repeated failures.
- Capture the upload size from the log; if large transfers always fail, inspect MTU/fragmentation or reduce upload chunk size.
Defensive patterns
Strategy: retry
Validate before calling
# before starting bulk transfers, ensure session health
if not g.server_host or g.quota <= 0:
# re-login instead of letting roundtrips fail
ok, reason = request_balance(g.config.login_account, g.config.login_password)
if not ok:
raise RuntimeError('session not ready: %s' % reason) Prevention
- Keep request_balance fresh so transfers never run on a dead session.
- Watch on_road_num vs target_on_roads divergence as an early failure signal.
- Retry failed roundtrips with backoff; notify waiters as the code already does.
When it happens
Trigger: The inner loop of roundtrip_task never matches the expected transfer_no before hitting its overall failure path — e.g. every attempt timed out (data_info['stat'] == 'timeout') or returned data for a different transfer. Caused by server-side drops, severe packet loss, or the session being reset mid-flight.
Common situations: Unstable connectivity to the x_tunnel server, server restart invalidating transfer numbers, quota/session expiry mid-transfer, or MTU/firewall middleboxes silently dropping the large upload_post_data.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/36a8da8f542018f0.
Report an issue: GitHub.