Repository navigation
TC-1012: cap /invoke upload bodies at 95 MiB with 413 - #317
Merged
Merged
Conversation
Contributor
Author
|
APPROVE: see TC-1012 |
Contributor
Author
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TC-1012. The node now enforces its own upload limit of 95 MiB (99,614,720 bytes). A body of exactly that size is accepted, and a body one byte longer gets 413. Requests to node.tinycloud.xyz reach the node on :8000 through the Cloudflare Worker without passing the ingress, so the node's own limit is the one that applies there.
Limits found (base 212a826)
There is no Rocket.toml and no
limitsconfig. Rocket's built-inlimitsapply only to its own data guards (Json,Stringand so on), not to the rawDatathat/invokereads. The limits that actually apply are the explicitData::opencalls intinycloud-node-server/src/routes/mod.rs:invoke_impl, mod.rs:1936)d.open(1u8.gigabytes()): 1 GB, and a longer body was cut off and stored without an errorbuild_batch_kv_inputs, mod.rs:1509)data.open(1u8.gigabytes()): past 1 GB, multer saw a truncated stream → 400whole_stream(99_614_720);StreamSizeExceeded→ 413 (fromnext_fieldandchunk)handle_duckdb_invoke, mod.rs:3123)d.open(100u8.megabytes()): 100 MB, cut off without an errorThe JSON bodies (
read_json_body, 1 MiB) and the share routes keep their own smaller limits, which already return 413.Tests
tc1012_kv_put_accepts_exactly_95_mib_and_refuses_one_more_byte_with_413: a signedkv/putthrough the real/invokeroute. A 99,614,720-byte body gets 2xx; 99,614,721 bytes gets 413.tc1012_multipart_kv_put_accepts_95_mib_body_and_refuses_one_more_byte_with_413: a multipart body of 99,614,720 bytes total gets 2xx; one byte more gets 413.Transfer-Encoding: chunked: 99,614,720 bytes →200 OK, 99,614,721 bytes →413 Payload Too Large.cargo test -p tinycloud-node --lib: 526/526 pass. In one of three full runs, threepolicy_v3::account_alias_testsfailed; they pass on their own and on rerun. Those tests are outside this change.cargo check -p tinycloud-node --features duckdb --testspasses, andcargo fmt --checkand clippy show no new warnings.deploy/ingress/test-redacted-logging.shnow runs the ingress withCLIENT_MAX_BODY_SIZE=95mand expects exactly 99,614,720 bytes → 200, 99,614,721 bytes → 413, and 99,614,721 bytes chunked over HTTP/1.1 → 413. It passes locally (DOCKER="sudo docker").Compose
This PR does not change
docker-compose.dstack-postgres.yaml, which the TC-959 N0 lock hash-pins. #309 keeps its approved bytes (32m, raw ca110b0b…), which ship with the N0 sidecar on 1.20.6. TheCLIENT_MAX_BODY_SIZE=32m→95mline moves to the main-release lineage in #315, which binds the release compose. Main's pre-N0 template andops/rollback/*.yamlstay at 32m on purpose. Until the release compose lands, main's compose still says 32m while the docs and the ingress test here say 95m.Not merged or deployed.