{"record":{"id":"2a67fffa18758fdd","repo":"rwf2/Rocket","slug":"unexpectedeof","errorCode":"UnexpectedEof","errorMessage":"data limit exceeded","messagePattern":"data limit exceeded","errorType":"http","errorClass":"io::Error","httpStatus":400,"severity":"error","filePath":"core/lib/src/data/capped.rs","lineNumber":262,"sourceCode":"}\n\nmacro_rules! impl_strict_from_data_from_capped {\n    ($T:ty) => (\n        #[crate::async_trait]\n        impl<'r> $crate::data::FromData<'r> for $T {\n            type Error = <$crate::data::Capped<Self> as $crate::data::FromData<'r>>::Error;\n\n            async fn from_data(\n                r: &'r $crate::Request<'_>,\n                d: $crate::Data<'r>\n            ) -> $crate::data::Outcome<'r, Self> {\n                use $crate::outcome::Outcome::*;\n                use std::io::{Error, ErrorKind::UnexpectedEof};\n\n                match <$crate::data::Capped<$T> as FromData>::from_data(r, d).await {\n                    Success(p) if p.is_complete() => Success(p.into_inner()),\n                    Success(_) => {\n                        let e = Error::new(UnexpectedEof, \"data limit exceeded\");\n                        Error((Status::BadRequest, e.into()))\n                    },\n                    Forward(d) => Forward(d),\n                    Error((s, e)) => Error((s, e)),\n                }\n            }\n        }\n    )\n}\n","sourceCodeStart":244,"sourceCodeEnd":272,"githubUrl":"https://github.com/rwf2/Rocket/blob/3a54d079aef060a8f732bd04ea54b0581a604087/core/lib/src/data/capped.rs#L244-L272","documentation":"Runtime error produced by the impl_from_data_capped!-style macro in core/lib/src/data/capped.rs: a FromData guard (e.g. strict Form<T>) wraps the raw data in Capped<T>, and when the stream completes but the guard reports is_complete() == false — i.e. the configured data limit was hit before the body ended — the wrapper returns an io::Error of kind UnexpectedEof ('data limit exceeded') and the request fails with 400 BadRequest. The limit comes from Rocket's limits config (e.g. limits.forms, default 32 KiB).","triggerScenarios":"POSTing a multipart/form or urlencoded body larger than limits.forms (default 32 KiB) to a route with a Form<T> guard; any capped guard whose limit the client exceeds. The boundary check is exact: hitting the cap without a terminating boundary yields an incomplete Capped value.","commonSituations":"File uploads routed through Form<T> instead of TempFile/Data; raising expectations in dev with small test payloads then receiving real-world sizes; forgetting Rocket's conservative 32 KiB default for forms after upgrading from an older version.","solutions":["Raise the limit in Rocket.toml: [default.limits] forms = \"2 MiB\" (or limits = { forms = \"2 MiB\" })","Switch file-upload fields to TempFile<'_> or Data<'_> which stream to disk instead of parsing through the forms limit","Use Capped<Form<T>> as the guard to accept oversized-but-parseable input and branch on is_complete()/n","Register a 400/413 catcher to return a friendly message when a client still exceeds the limit"],"exampleFix":"# before\n# Rocket.toml (defaults: forms = 32 KiB)\n#[post(\"/submit\", data = \"<form>\")]\nfn submit(form: Form<Report>) { }\n\n# after\n# Rocket.toml\n[default.limits]\nforms = \"2 MiB\"\nfiles = \"10 MiB\"\n\n#[post(\"/submit\", data = \"<form>\")]\nfn submit(form: Form<Report>) { }","handlingStrategy":"try-catch","validationCode":"// reject oversized form bodies before the guard parses them\n#[post(\"/submit\", data = \"<data>\")]\nfn submit(data: Data<'_>) -> Status {\n    let forms_limit = 2 * 1024 * 1024;\n    match data.open(forms_limit.into()).into_string().await {\n        Ok(s) if s.is_complete() => { /* parse manually or forward */ Status::Ok }\n        Ok(_) => Status::PayloadTooLarge,\n        Err(_) => Status::BadRequest,\n    }\n}","typeGuard":null,"tryCatchPattern":"// accept-and-inspect oversized input instead of failing hard\n#[post(\"/submit\", data = \"<form>\")]\nfn submit(form: Capped<Form<Report>>) -> Status {\n    if form.is_complete() { Status::Ok } else { Status::PayloadTooLarge }\n}\n\n// and a catcher for other routes\n#[catch(400)]\nfn bad_request(_: &Request) -> &'static str { \"payload too large or malformed\" }","preventionTips":["Set limits.forms in Rocket.toml deliberately for every deployment, don't rely on the 32 KiB default","Route file uploads through TempFile<'_>/Data<'_>, not Form","Client-side: send multipart for anything binary or large"],"tags":["rust","rocket","form-data","limits","runtime","request-body"],"backgroundTag":"request-body-too-large","analyzedSha":"3a54d079aef060a8f732bd04ea54b0581a604087","analyzedAt":"2026-08-16T22:01:48.395Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}