XX-net/XX-Net · warning

session try to run but is running.

Error message

session try to run but is running.

What it means

proxy_session.start() was called while self.running was already True. The session is a singleton-ish long-running multiplexed tunnel; start() guards against double-start and just logs this warning and returns True (treating it as already started) without reinitializing state.

Source

Thrown at code/default/x_tunnel/local/proxy_session.py:119

        # if no data left, set to 0
        self.oldest_received_time = 0

        self.last_state = {
            "timeout": 0,
        }
        if g.config.enable_tls_relay:
            threading.Thread(target=self.reporter, name="reporter").start()

        if g.config.upload_logs:
            threading.Thread(target=upload_logs_thread, name="upload_logs").start()

        self.timeout_check_th = threading.Thread(target=self.timeout_checker, name="timeout_check")
        self.timeout_check_th.start()

    def start(self):
        with self.lock:
            if self.running is True:
                xlog.warn("session try to run but is running.")
                return True

            self.session_id = utils.to_bytes(utils.generate_random_lowercase(8))
            self.last_conn_id = 0
            self.last_transfer_no = 0
            self.conn_list = {}
            self.transfer_list = {}
            self.last_send_time = time.time()
            self.last_receive_time = 0

            # speed calculation
            self.traffic_upload = 0
            self.traffic_download = 0
            self.last_traffic_upload = 0
            self.last_traffic_download = 0
            self.last_traffic_reset_time = time.time()

            # sn => (payload, send_time)

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Guard calls to start() with your own running check or call stop() before start() when you intend to restart.
  2. Audit for double invocation paths (auto-start thread plus explicit start) and serialize them with a lock.
  3. Treat this warning as benign if intentional (idempotent start) — no state is corrupted.

Example fix

# before
session.start()  # may be called twice

# after
if not session.running:
    session.start()
Defensive patterns

Strategy: validation

Validate before calling

if not session.running:
    session.start()
else:
    pass  # already started; skip

Type guard

def is_started(session) -> bool:
    return bool(getattr(session, 'running', False))

Prevention

When it happens

Trigger: Calling start() twice, e.g. from two worker threads, or from both auto-start logic and an explicit user start, without waiting for the previous session to stop.

Common situations: Launcher code that starts the tunnel on config change while it is already running; race between an auto-restart thread and manual start; plugin reload re-invoking initialization.

Related errors


AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27). Data as JSON: /api/errors/c1cffaec0123eeb6. Report an issue: GitHub.