XX-net/XX-Net · error
api:%s parse json:%s fail:%r
Error message
api:%s parse json:%s fail:%r
What it means
The control-plane API returned HTTP 200 but the (decrypted) body is not valid JSON. g.last_api_error is set to 'parse json fail' and call_api returns (False, 'parse json fail').
Source
Thrown at code/default/x_tunnel/local/proxy_session.py:1208
break
time_cost = time.time() - start_time
if status != 200:
reason = "status:%r" % status
xlog.warn("api:%s fail:%s t:%d", path, reason, time_cost)
g.last_api_error = reason
return False, reason
content = decrypt_data(content)
if isinstance(content, memoryview):
content = content.tobytes()
content = utils.to_str(content)
try:
info = json.loads(content)
except Exception as e:
g.last_api_error = "parse json fail"
xlog.warn("api:%s parse json:%s fail:%r", path, content, e)
return False, "parse json fail"
res = info["res"]
if res != "success":
g.last_api_error = info["reason"]
xlog.warn("api:%s fail:%s", path, info["reason"])
return False, info["reason"]
xlog.info("api:%s success t:%d", path, time_cost * 1000)
g.last_api_error = ""
return True, info
except Exception as e:
xlog.exception("order e:%r", e)
g.last_api_error = "%r" % e
return False, "except:%r" % e
center_login_process = FalseView on GitHub (pinned to cfa5bc17b6)
Solutions
- Check the logged raw content to see what was actually returned (HTML page → interception; garbage → key mismatch)
- Re-login / restart to re-establish session encryption keys
- Bypass interfering middleboxes or change network
- Report server format change if content is consistently non-JSON
Defensive patterns
Strategy: fallback
Type guard
def looks_like_api_json(content: bytes) -> bool:
s = utils.to_str(content).lstrip()
return s.startswith('{') or s.startswith('[') Try / catch
try:
info = json.loads(content)
except Exception:
return False, 'parse json fail' # keep session; retry later Prevention
- Detect HTML/intercepted bodies and trigger re-login
- Don't assume 200 implies JSON; validate content type/shape
When it happens
Trigger: Server returns HTML error page, plain-text message, or empty body with 200; decryption produced garbage due to key/session mismatch; content truncated by proxies.
Common situations: Captive portal or intercepting proxy rewriting responses, wrong session key after re-login, server bug or format change.
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
- login_session %s json error:%r
- api:%s fail:%s t:%d
- api:%s fail:%s
- query_dns_from_xxnet %s json:%s parse fail:%s
- XTunnelNotRunning
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/6996322153af8851.
Report an issue: GitHub.