XX-net/XX-Net · error · GAE_Exception
600
600
Error message
get protocol head fail
What it means
GAE_Exception 600 thrown in unpack_response when the first 2-byte protocol header read from the GAE connection returns empty. The GAE proxy protocol prefixes each response with a 2-byte big-endian header length; an empty read means the server/connection closed before sending any payload, so the response cannot be parsed.
Source
Thrown at code/default/gae_proxy/local/gae_handler.py:285
payload += b'X-URLFETCH-%s: %d\r\n' % (k, v)
else:
payload += b'X-URLFETCH-%s: %s\r\n' % (k, utils.to_bytes(v))
payload = deflate(payload)
body = b'%s%s%s' % (struct.pack('!h', len(payload)), payload, body)
request_headers = {}
request_headers[b'Content-Length'] = str(len(body))
# request_headers 只有上面一项
return request_headers, body
def unpack_response(response):
try:
data = response.task.read(size=2)
if not data:
raise GAE_Exception(600, "get protocol head fail")
if len(data) !=2:
raise GAE_Exception(600, "get protocol head fail, data:%s, len:%d" % (data, len(data)))
headers_length, = struct.unpack('!h', data)
data = response.task.read(size=headers_length)
if not data:
raise GAE_Exception(600,
"get protocol head fail, len:%d" % headers_length)
raw_response_line, headers_data = inflate(data).split(b'\r\n', 1)
rl = raw_response_line.split()
response.app_status = int(rl[1])
if len(rl) >=3:
response.app_reason = rl[2].strip()
headers_block, app_msg = headers_data.split(b'\r\n\r\n')
headers_pairs = headers_block.split(b'\r\n')View on GitHub (pinned to cfa5bc17b6)
Solutions
- Retry the request — the upper layer (request_gae_proxy) already retries; persistent failure means the appid or IP is bad
- Update to the current XX-Net version so the protocol matches the deployed GAE app
- Deploy/repair your GAE appid (check the appengine admin console for errors)
- Switch to a different Google IP / let the IP manager re-scan working IPs
Defensive patterns
Strategy: retry
Try / catch
try:
response = request_gae_proxy(method, url, headers, body)
except GAE_Exception as e:
if e.code == 600:
# transport/protocol level; safe to retry on a new connection
response = request_gae_proxy(method, url, headers, body)
else:
raise Prevention
- Keep multiple healthy appids and IPs configured so retries land on good routes
- Run the latest XX-Net version to avoid protocol mismatches
- Treat repeated 600s from one IP/appid as a signal to bench it
When it happens
Trigger: Calling request_gae_proxy whose inner request_gae_server succeeded at HTTP level but the app returned zero bytes; the connection was closed (worker.close) or reset between the HTTP response and body read; server-side error producing empty body.
Common situations: GAE appid misbehaving or deleted, flaky connection to Google IPs, IP blocked/reset mid-response, GAE platform incident, protocol mismatch after XX-Net version change.
Related errors
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/1e35f1f62b01a478.
Report an issue: GitHub.