{"id":"8ce8c13fb0a92586","repo":"hyperium/hyper","slug":"invalid-chunk-size-line-invalid-size","errorCode":null,"errorMessage":"Invalid chunk size line: Invalid Size","messagePattern":"Invalid chunk size line: Invalid Size","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src/proto/h1/decode.rs","lineNumber":399,"sourceCode":"        let radix = 16;\n        match byte!(rdr, cx) {\n            b @ b'0'..=b'9' => {\n                *size = or_overflow!(size.checked_mul(radix));\n                *size = or_overflow!(size.checked_add(u64::from(b - b'0')));\n            }\n            b @ b'a'..=b'f' => {\n                *size = or_overflow!(size.checked_mul(radix));\n                *size = or_overflow!(size.checked_add(u64::from(b + 10 - b'a')));\n            }\n            b @ b'A'..=b'F' => {\n                *size = or_overflow!(size.checked_mul(radix));\n                *size = or_overflow!(size.checked_add(u64::from(b + 10 - b'A')));\n            }\n            b'\\t' | b' ' => return Poll::Ready(Ok(ChunkedState::SizeLws)),\n            b';' => return Poll::Ready(Ok(ChunkedState::Extension)),\n            b'\\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),\n            _ => {\n                return Poll::Ready(Err(io::Error::new(\n                    io::ErrorKind::InvalidInput,\n                    \"Invalid chunk size line: Invalid Size\",\n                )));\n            }\n        }\n        Poll::Ready(Ok(ChunkedState::Size))\n    }\n    fn read_size_lws<R: MemRead>(\n        cx: &mut Context<'_>,\n        rdr: &mut R,\n    ) -> Poll<Result<ChunkedState, io::Error>> {\n        trace!(\"read_size_lws\");\n        match byte!(rdr, cx) {\n            // LWS can follow the chunk size, but no more digits can come\n            b'\\t' | b' ' => Poll::Ready(Ok(ChunkedState::SizeLws)),\n            b';' => Poll::Ready(Ok(ChunkedState::Extension)),\n            b'\\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),\n            _ => Poll::Ready(Err(io::Error::new(","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/hyperium/hyper/blob/084473f728f9d07b3be5845475aa2f62ed9ff579/src/proto/h1/decode.rs#L381-L417","documentation":"Thrown in the Size state (src/proto/h1/decode.rs:399) while consuming subsequent bytes of the chunk-size token. Only hex digits, linear whitespace (tab/space), ';' (start of an extension), or '\\r' (end of the size line) are accepted; any other byte is reported as io::ErrorKind::InvalidInput. It means the size token contained an illegal character after a valid leading hex digit.","triggerScenarios":"A chunk-size line like \"1X\\r\\n\", \"1 invalid extension\\r\\n\", or \"1 A\\r\\n\" where a non-hex, non-terminator byte appears inside the size field. Also triggered by decimal sizes (\"10\\r\\n\" is fine because 1 and 0 are hex, but something like \"1g\\r\\n\" is not).","commonSituations":"A sender that writes the chunk length in decimal but appends a unit suffix (\"16 bytes\\r\\n\"); a debug logger or middleware that injects text into the size line; a peer that confuses chunk size with Content-Length formatting.","solutions":["Inspect the exact bytes of the failing chunk-size line and locate the non-hex character.","Ensure the sender emits only hex digits followed by optional LWS/extension and CRLF (\"{:x}\\r\\n\").","Remove any middleware that decorates the size line with units, comments, or spaces before the CRLF."],"exampleFix":"// before: decimal size with unit suffix\nwrite!(w, \"{} bytes\\r\\n\", len).await?; // 'bytes' -> error 21\n\n// after: lowercase hex, no suffix\nwrite!(w, \"{:x}\\r\\n\", len).await?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match body.data().await {\n    Some(Ok(b)) => { /* process */ }\n    Some(Err(e)) => {\n        let kind = e.source()\n            .and_then(|s| s.downcast_ref::<std::io::Error>())\n            .map(|io| io.kind());\n        if matches!(kind, Some(std::io::ErrorKind::InvalidInput)) {\n            tracing::warn!(error=%e, \"invalid chunk size token; aborting body\");\n            return Ok(None);\n        }\n        return Err(e.into());\n    }\n    None => {}\n}","preventionTips":["Format chunk sizes with \"{:x}\"; never append units, spaces-with-text, or comments.","If you log chunk metadata, write it to a trailer or stderr — not into the size line.","Fuzz-test your chunk encoder against hyper's decoder."],"tags":["http","http1","chunked","framing","hyper","rust"],"analyzedSha":"084473f728f9d07b3be5845475aa2f62ed9ff579","analyzedAt":"2026-08-06T01:20:18.522Z","schemaVersion":2}