{"record":{"id":"0a693c631eeb9044","repo":"tursodatabase/turso","slug":"http-request-length-overflows-content-length","errorCode":null,"errorMessage":"HTTP request length overflows: {content_length}","messagePattern":"HTTP request length overflows: (.+?)","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":1265,"sourceCode":"\n    let mut page = vec![0u8; PAGE_SIZE];\n    if conn.try_wal_watermark_read_page(1, &mut page, Some(max_frame))? {\n        Ok(db_size_from_page(&page) as u64)\n    } else {\n        Ok(0)\n    }\n}\n\nfn db_size_from_page(page: &[u8]) -> u32 {\n    u32::from_be_bytes(page[28..32].try_into().unwrap())\n}\n\n/// A client controls Content-Length, so the end of the body has to be\n/// computed without trusting it to fit.\nfn request_end(header_end: usize, content_length: usize) -> Result<usize> {\n    (header_end + 4)\n        .checked_add(content_length)\n        .ok_or_else(|| anyhow!(\"HTTP request length overflows: {content_length}\"))\n}\n\nfn find_header_end(data: &[u8], start: usize) -> Option<usize> {\n    (start..data.len().saturating_sub(3)).find(|&i| &data[i..i + 4] == b\"\\r\\n\\r\\n\")\n}\n\nfn parse_content_length(headers: &str) -> Option<usize> {\n    for line in headers.lines() {\n        let lower = line.to_lowercase();\n        if lower.starts_with(\"content-length:\") {\n            let value = line.split(':').nth(1)?.trim();\n            return value.parse().ok();\n        }\n    }\n    None\n}\n\nfn parse_http_request(data: &[u8]) -> Result<(String, String, Vec<u8>)> {","sourceCodeStart":1247,"sourceCodeEnd":1283,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/cli/sync_server.rs#L1247-L1283","documentation":"TursoSyncServer parses HTTP by hand; request_end computes header_end + 4 + content_length with checked_add because, as the code comment states, the client fully controls Content-Length. This error fires when that sum would overflow usize - i.e. a client sent a Content-Length near usize::MAX (2^64-1 on 64-bit). It is a hardening guard against absurd headers rather than a normal failure.","triggerScenarios":"handle_connection reads headers containing e.g. 'Content-Length: 18446744073709551615'; parse_content_length parses it into usize and (header_end + 4).checked_add(content_length) returns None in request_end.","commonSituations":"Port scanners or hostile probes sending overflow-style headers; buggy hand-rolled HTTP clients computing Content-Length with wrapped/negative arithmetic; fuzzers targeting the sync port.","solutions":["Fix the client to send a Content-Length equal to the actual body byte count","If exposing the server, front it with a proxy that enforces sane body-size limits","When embedding the server, reject requests with Content-Length above a MAX_BODY_BYTES cap before reading the body"],"exampleFix":"// before (client): stale or wrapped length\nlet len = body.capacity(); // wrong: capacity, not len\nwrite!(stream, \"Content-Length: {len}\\r\\n\\r\\n\")?;\n\n// after: derive from the exact body\nwrite!(stream, \"Content-Length: {}\\r\\n\\r\\n\", body.len())?;\nstream.write_all(&body)?;","handlingStrategy":"validation","validationCode":"// Cap Content-Length before computing the body end:\nconst MAX_BODY_BYTES: usize = 64 * 1024 * 1024;\nfn content_length_acceptable(content_length: usize) -> bool {\n    content_length <= MAX_BODY_BYTES\n}","typeGuard":null,"tryCatchPattern":"let total_expected = match request_end(header_end, content_length) {\n    Ok(total) => total,\n    Err(err) if err.to_string().starts_with(\"HTTP request length overflows\") => {\n        // hostile or broken client: answer 400 and close\n        return Err(err);\n    }\n    Err(err) => return Err(err),\n};","preventionTips":["Always derive Content-Length from the actual body length at send time","Keep the checked_add in request_end intact - never plain addition on client-controlled values","Front public deployments with a proxy enforcing body-size limits"],"tags":["http","sync-server","content-length","overflow","security"],"backgroundTag":"http-content-length-overflow","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}