3 days ago
Hello Railway Support,
Could you inspect an existing request trace from our private Trailhead QA service?
No new load test is requested.
Request ID: lWxD3TyhTlqLMRL321mRUA
Timestamp: 2026-10-16T01:08:05.930013428Z
Deployment: 7137241c-240c-448f-8222-4eeaf5f91efb
Region: europe-west4-drams3a
Request: POST /api/map-context/search
The retained edge row reports HTTP200,183ms total duration,37920txBytes,
683rxBytes, upstream HTTP/1.1 and empty upstreamErrors/responseDetails.
The physical Android client (React Native0.81.5/OkHttp4.12) recorded an HTTP/2
StreamResetException with CANCEL during response-body reading: status200,
body-start callback seen, no body-end callback, and no canceled callback seen
before the terminal record. JavaScript reported a network failure before decode.
We have not established whether this came from an explicit stream reset,
connection EOF, a local cancellation race or another hop. Edge byte counts and
ASGI handoff are not proof of full delivery to the client. We are not attributing
the cause to Railway based only on this record.
Can your trace show the downstream termination reason, whether a reset was sent
or received, the origin response-completion state, and whether all response bytes
were flushed? Please let us know if any documented known issue applies to this
specific trace before we consider an application or protocol change.
The QA deployment is now removed and its original settings restored. This
request contains no account credentials, customer data or private response body.
Thank you,
Trailhead
5 Replies
3 days ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • 3 days ago
3 days ago
Most likely causes on Android (React Native):
1- Search debounce / Abort race (Top suspect): An AbortController.abort() fired on a previous keystroke or screen unmount while the ~38 KB response was still streaming. In OkHttp, this immediately drops the stream with RST_STREAM (CANCEL) and surfaces as a network failure in JS.
2- Aggressive client timeout: A client-side timeout under ~400 ms triggered before the mobile radio could finish reading all data frames.
Plz Check followings:
1- Verify if the search input cancels in-flight requests on new keystrokes, and ensure AbortError / cancelled requests are caught and ignored in JS rather than treated as network crashes.
2- Confirm client-side read/request timeouts are set to at least 5–10 seconds for payloads this size over mobile networks.
3- To confirm whether the app itself initiated the reset, log call.isCanceled() in an OkHttp EventListener on the Android client.
3 days ago
Thanks. For this request the app's map search call passes no AbortSignal and sets no JS timeout, and OkHttp's own canceled callback did not fire (canceled:false) before the StreamResetException. So a client abort or timeout doesn't match this trace. We're still hoping Railway can share the edge-side termination reason for request ID lWxD3TyhTlqLMRL321mRUA.
3 days ago
https://station.railway.com/questions/edge-hikari-intermittently-sends-rst-s-3ed8fbb0
Railway confirmed an upstream dependency bug and deployed a fix. Multiple independent reports showed HTTP 200 at the origin followed by OkHttp StreamResetException(CANCEL), with HTTP/1.1 eliminating the failures.
My leading hypothesis is a regression of that issue in the edge-to-client HTTP/2 response path.
The quickest workaround is to temporarily pin Android OkHttp to Protocol.HTTP_1_1
3 days ago
Update: we found a bug on our side that can produce exactly this symptom. Our private QA wrapper blocked socket.sendmsg for the whole server process. On Python 3.12, asyncio flushes a partially sent response with sendmsg, so a response that doesn't fit in one send is aborted mid-body. We reproduced that locally and are fixing it. From this trace we can't tell whether it caused this request or whether it was the edge RST issue linked above, because we don't know if the 37,920 tx bytes were the full body. We'll retest after the fix and follow up here if it recurs. Thanks.
5 hours ago
Actually your Python 3.12 asyncio fix for socket.sendmsg directly solves this. When an async server blocks a socket send mid-response, the event loop flushes a partial payload and terminates the stream early. The Railway edge proxy gets a truncated upstream HTTP/1.1 stream after already dispatching the HTTP 200 header block, forcing the proxy to send an HTTP/2 RST_STREAM CANCEL down to OkHttp. If your local reproduction matches that truncated byte count, fixing the buffer flush will keep the stream intact.
