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

  1. Retry the request — the upper layer (request_gae_proxy) already retries; persistent failure means the appid or IP is bad
  2. Update to the current XX-Net version so the protocol matches the deployed GAE app
  3. Deploy/repair your GAE appid (check the appengine admin console for errors)
  4. 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

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.