Adversarial proxy returned a transient 502 for a rejected 3 MiB Appearance body #1256

Open
opened 2026-10-06 23:42:15 +00:00 by kayg · 2 comments
Owner

Round 31 oversized Appearance request got a transient proxy 502 (#1202)

Product 139d4378e, release build, after the Editor restart phase:

Appearance PUT burst: p95=0.246s (31 concurrent requests)
!! appearance oversized body 3 MiB: 502 b'local adversarial server is unavailable'

The text is produced by tests/adversarial/editor-proxy.mjs when its upstream request errors. Both front and backend /healthz answered 200 immediately after diagnosis. A focused request with the exact same oversized_appearance_body(3 * 1024 * 1024) shape later returned 413 directly and through the proxy. The server stayed live and subsequent Note creates succeeded. No panic or stack overflow was found.

This does not establish a server crash. An early-response/write-error race in the fixture proxy is possible but is not proved. Existing proxy-early-response.test.mjs covers immediate 413s before/after Continue; extend its 3 MiB and concurrent body-rejection coverage and diagnose the transport error under a burst. Do not hide the 502 by changing an expectation. This transient finding is recorded while the full runner continues.

Round 31 oversized Appearance request got a transient proxy 502 (#1202) Product `139d4378e`, release build, after the Editor restart phase: ```text Appearance PUT burst: p95=0.246s (31 concurrent requests) !! appearance oversized body 3 MiB: 502 b'local adversarial server is unavailable' ``` The text is produced by `tests/adversarial/editor-proxy.mjs` when its upstream request errors. Both front and backend `/healthz` answered 200 immediately after diagnosis. A focused request with the exact same `oversized_appearance_body(3 * 1024 * 1024)` shape later returned 413 directly and through the proxy. The server stayed live and subsequent Note creates succeeded. No panic or stack overflow was found. This does not establish a server crash. An early-response/write-error race in the fixture proxy is possible but is not proved. Existing `proxy-early-response.test.mjs` covers immediate 413s before/after Continue; extend its 3 MiB and concurrent body-rejection coverage and diagnose the transport error under a burst. Do not hide the 502 by changing an expectation. This transient finding is recorded while the full runner continues.
Author
Owner

Correction and stronger evidence for #1256: the first focused 413 used a different unknown-field body. The exact Appearance background.light.color body reproduces the problem: direct server 413, Node fixture proxy 502. Bun preserves that 3 MiB rejection, but an expanded test also reproduces 502 for larger streamed bodies after the peer reads a chunk. The underlying server remains live.

The fixture fix is in progress: retain the real upstream response with native streaming forwarding, with regression coverage before/after Continue, after the first body chunk, a bounded burst and binary collaboration forwarding. No existing expected 413 is changed. Both exact live shapes and the complete proxy regression must pass before committing this fix. This is a fixture transport defect; the job is not claiming a clean adversarial exit while its old proxy is running.

Correction and stronger evidence for #1256: the first focused 413 used a different unknown-field body. The exact Appearance `background.light.color` body reproduces the problem: direct server 413, Node fixture proxy 502. Bun preserves that 3 MiB rejection, but an expanded test also reproduces 502 for larger streamed bodies after the peer reads a chunk. The underlying server remains live. The fixture fix is in progress: retain the real upstream response with native streaming forwarding, with regression coverage before/after Continue, after the first body chunk, a bounded burst and binary collaboration forwarding. No existing expected 413 is changed. Both exact live shapes and the complete proxy regression must pass before committing this fix. This is a fixture transport defect; the job is not claiming a clean adversarial exit while its old proxy is running.
Author
Owner

Fixed fixture transport in b81414b0c (#1256). The runner now uses Bun. Large ordinary bodies use native fetch with a bounded backpressure bridge; upstream cancellation drains the frontend rather than destroying it before the 413 is read. Raw encoded dot paths and Fetch-forbidden methods keep the compatibility client. Redirects are not followed, compressed bytes and separate cookies are preserved, and binary collaboration still forwards. The Bun fetch options were checked against the official reference.

Focused regression output:

# tests 15
# suites 0
# pass 15
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 2395.786292
PASS exact live Appearance payload: direct 413; corrected proxy 413
PASS exact live Photos Undo payload: direct 413; corrected proxy 413

Coverage includes 200 KB, 3 MiB, 5 MiB and >8 MiB bodies before/after Continue and after one body chunk; four concurrent requests per case; raw DAV dot segments; manual redirects; separate Set-Cookie values; exact compressed response bytes; binary collaboration. No expected 413 was changed. The ongoing full round keeps its already-started Node proxy, so its two historical proxy 502 findings remain in the report. No full-suite loop is started. The release server returned 413 directly in both cases and stayed live.

Fixed fixture transport in `b81414b0c` (#1256). The runner now uses Bun. Large ordinary bodies use native fetch with a bounded backpressure bridge; upstream cancellation drains the frontend rather than destroying it before the 413 is read. Raw encoded dot paths and Fetch-forbidden methods keep the compatibility client. Redirects are not followed, compressed bytes and separate cookies are preserved, and binary collaboration still forwards. The Bun fetch options were checked against [the official reference](https://bun.com/reference/globals/BunFetchRequestInit). Focused regression output: ```text # tests 15 # suites 0 # pass 15 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 2395.786292 PASS exact live Appearance payload: direct 413; corrected proxy 413 PASS exact live Photos Undo payload: direct 413; corrected proxy 413 ``` Coverage includes 200 KB, 3 MiB, 5 MiB and >8 MiB bodies before/after Continue and after one body chunk; four concurrent requests per case; raw DAV dot segments; manual redirects; separate Set-Cookie values; exact compressed response bytes; binary collaboration. No expected 413 was changed. The ongoing full round keeps its already-started Node proxy, so its two historical proxy 502 findings remain in the report. No full-suite loop is started. The release server returned 413 directly in both cases and stayed live.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1256
No description provided.