actix/actix-web · error · io::Error

Invalid chunk size line: Size is too big

Error message

Invalid chunk size line: Size is too big

What it means

Raised in read_size (chunked.rs:81) when accumulating the hex chunk size would overflow a u64 - i.e. size.checked_mul(16) returns None. This is an intentional guard (logged at debug level, chunked.rs:80) against pathologically large or malicious chunk sizes such as the smuggler payload f0000000000000003 tested in hrs_chunk_size_overflow (chunked.rs:407).

Solutions

  1. No legitimate chunk size approaches 2^64; treat this as a malicious or broken client and close the connection.
  2. Ensure upstream proxies normalize/sanitize chunked framing.
  3. Cap request body sizes via PayloadConfig so oversized bodies are rejected earlier.

Example fix

// before (attack)
"f0000000000000003\r\n..."
// after (valid small chunk)
"10\r\n<16 bytes>\r\n0\r\n\r\n"
Defensive patterns

Strategy: try-catch

Try / catch

match payload.next().await {
    Some(Err(PayloadError::Io(e))) if e.kind() == io::ErrorKind::InvalidInput =>
        return HttpResponse::BadRequest().finish(), // oversized chunk size
    _ => { /* ... */ }
}

Prevention

When it happens

Trigger: A chunk-size line declares a value whose hexadecimal representation exceeds 64 bits, e.g. "f0000000000000003\r\n". Each hex digit shifts left by 4 bits; enough digits overflow u64.

Common situations: Request-smuggling / desync attack probes; a malformed client; fuzzing the HTTP parser.

Related errors


AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09). Data as JSON: /api/errors/000c1413b161d1e3. Report an issue: GitHub.

Appendix: source

Thrown at actix-http/src/h1/chunked.rs:81

            b'\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),
            _ => {
                return Poll::Ready(Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    "Invalid chunk size line: Invalid Size",
                )));
            }
        };

        match size.checked_mul(radix) {
            Some(n) => {
                *size = n;
                *size += rem as u64;

                Poll::Ready(Ok(ChunkedState::Size))
            }
            None => {
                debug!("chunk size would overflow u64");
                Poll::Ready(Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    "Invalid chunk size line: Size is too big",
                )))
            }
        }
    }

    fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
        match byte!(rdr) {
            // LWS can follow the chunk size, but no more digits can come
            b'\t' | b' ' => Poll::Ready(Ok(ChunkedState::SizeLws)),
            b';' => Poll::Ready(Ok(ChunkedState::Extension)),
            b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
            _ => Poll::Ready(Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                "Invalid chunk size linear white space",
            ))),
        }

View on GitHub (pinned to 4d435abc28)