XX-net/XX-Net · warning

login_session %s json error:%r

Error message

login_session %s json error:%r

What it means

After a successful login response (res == 0), the client tries to json.loads(message) to inspect flags like full_log. If the message body is not valid JSON, this warning is logged and msg_info degrades to {}; the login still succeeds and returns True.

Source

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

                if isinstance(message, memoryview):
                    message = message.tobytes()

                if magic != b"P" or protocol_version != g.protocol_version or pack_type != 1:
                    xlog.error("login_session time:%d head error:%s", 1000 * time_cost, utils.str2hex(info[:6]))
                    return False

                if res != 0:
                    g.last_api_error = "session server login fail, code:%d msg:%s" % (res, message)
                    xlog.warn("login_session time:%d fail, res:%d msg:%s", 1000 * time_cost, res, message)
                    return False

                try:
                    msg_info = json.loads(message)
                    if msg_info.get("full_log"):
                        xlog.debug("keep full log")
                        keep_log(temp=True)
                except Exception as e:
                    xlog.warn("login_session %s json error:%r", message, e)
                    msg_info = {}

                g.http_client.set_session_host(g.server_host)
                g.last_api_error = ""
                xlog.info("login_session %s time:%d msg:%s", self.session_id, 1000 * time_cost, message)
                return True
            except Exception as e:
                xlog.exception("login_session e:%r", e)
                time.sleep(1)

        return False

    def create_conn(self, sock, host, port, log=False):
        if not self.running:
            xlog.debug("session not running, try to connect")
            time.sleep(1)
            return None

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Usually harmless — login still succeeds; verify session works via subsequent API calls
  2. Update XX-Net to a version matching the current server message format
  3. Check for MITM/captive portal interference on the connection
  4. Capture the raw message string from the log and report the format change
Defensive patterns

Strategy: fallback

Type guard

def is_json_login_message(message: bytes) -> bool:
    try:
        json.loads(utils.to_str(message))
        return True
    except Exception:
        return False

Try / catch

try:
    info = json.loads(message)
except Exception:
    info = {}  # login still succeeded; proceed without flags

Prevention

When it happens

Trigger: Session server returns a non-JSON success message body (plain text status, empty body, or HTML proxy page) while res == 0; this is a server-side format change.

Common situations: Server version change altering the login reply format, an intermediary (captive portal/proxy) rewriting the response body, or truncated payload from network issues.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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