XX-net/XX-Net · warning
forward_local read payload failed:%s
Error message
forward_local read payload failed:%s
What it means
In forward_local, the proxy tried to read the request body indicated by Content-Length from the client socket (self.rfile.read) and the read raised — usually a client disconnect, invalid Content-Length, or socket timeout — so the local forwarding is aborted.
Source
Thrown at code/default/gae_proxy/local/proxy_handler.py:104
self.__class__.do_PUT = self.__class__.do_METHOD
self.__class__.do_POST = self.__class__.do_METHOD
self.__class__.do_HEAD = self.__class__.do_METHOD
self.__class__.do_DELETE = self.__class__.do_METHOD
self.__class__.do_OPTIONS = self.__class__.do_METHOD
def forward_local(self):
"""
If browser send localhost:xxx request to GAE_proxy,
we forward it to localhost.
"""
request_headers = dict((k.title(), v) for k, v in list(self.headers.items()))
payload = b''
if b'Content-Length' in request_headers:
try:
payload_len = int(request_headers.get(b'Content-Length', 0))
payload = self.rfile.read(payload_len)
except Exception as e:
xlog.warn('forward_local read payload failed:%s', e)
return
response = simple_http_client.request(self.command, self.path, request_headers, payload)
if not response:
xlog.warn("forward_local fail, command:%s, path:%s, headers: %s, payload: %s",
self.command, self.path, request_headers, payload)
return
out_list = []
out_list.append(b"HTTP/1.1 %d\r\n" % response.status)
for key in response.headers:
key = key.title()
out_list.append(b"%s: %s\r\n" % (key, response.headers[key]))
out_list.append(b"\r\n")
out_list.append(response.text)
self.wfile.write(b"".join(out_list))
View on GitHub (pinned to cfa5bc17b6)
Solutions
- Verify the client actually sends the declared body length (curl -v / packet capture)
- Increase socket timeout if large uploads are being cut off
- Sanitize Content-Length (strip, validate digits) before int() to avoid ValueError on malformed headers
- Retry the request — transient client disconnects are common and benign
Example fix
# before
payload_len = int(request_headers.get(b'Content-Length', 0))
payload = self.rfile.read(payload_len)
# after
try:
payload_len = int(request_headers.get(b'Content-Length', 0))
except ValueError:
return
payload = self.rfile.read(payload_len) Defensive patterns
Strategy: try-catch
Validate before calling
cl = request_headers.get(b'Content-Length', b'')
if cl and not cl.strip().isdigit():
respond_400(); return Try / catch
try:
payload = self.rfile.read(payload_len)
except Exception as e:
xlog.warn('forward_local read payload failed:%s', e)
return # simply drop the half-sent request; client is gone Prevention
- Validate Content-Length is numeric before parsing
- Set a sane socket timeout so aborted clients fail fast
- Send Content-Length-correct bodies from your HTTP clients
When it happens
Trigger: A client sends a request with a Content-Length header but closes the connection before sending the full body; Content-Length is non-numeric so int() raises; or the socket times out mid-body. read() raises and forward_local returns without forwarding.
Common situations: Browsers/tools aborting requests (page navigation, cancel), misbehaving HTTP clients sending malformed Content-Length, mobile clients dropping connections, aggressive timeouts on large uploads.
Related errors
- https %r connect to %s:%d conn:%d closed.
- gae send response fail. %r
- forward_local fail, command:%s, path:%s, headers: %s, payloa
- CONNECT %s port:%d not support
- go_AGENT OPTIONS not supported by GAE
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/0f0c71ea28e41dc8.
Report an issue: GitHub.