{"record":{"id":"30b78b1d8c71ea7c","repo":"actix/actix-web","slug":"invalid-range-header-invalid-syntax","errorCode":null,"errorMessage":"invalid Range header: invalid syntax","messagePattern":"invalid Range header: invalid syntax","errorType":"http","errorClass":"ParseRangeErr","httpStatus":416,"severity":"warning","filePath":"actix-files/src/range.rs","lineNumber":29,"sourceCode":"\nimpl From<http_range::HttpRangeParseError> for HttpRangeParseError {\n    fn from(err: http_range::HttpRangeParseError) -> Self {\n        match err {\n            http_range::HttpRangeParseError::InvalidRange => Self::InvalidRange,\n            http_range::HttpRangeParseError::NoOverlap => Self::NoOverlap,\n        }\n    }\n}\n\n#[derive(Debug, Clone, Error)]\n#[non_exhaustive]\npub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);\n\nimpl fmt::Display for ParseRangeErr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid Range header: \")?;\n        f.write_str(match self.0 {\n            HttpRangeParseError::InvalidRange => \"invalid syntax\",\n            HttpRangeParseError::NoOverlap => \"range starts after end of content\",\n        })\n    }\n}\n\n/// HTTP Range header representation.\n#[derive(Debug, Clone, Copy)]\npub struct HttpRange {\n    /// Start of range.\n    pub start: u64,\n\n    /// Length of range.\n    pub length: u64,\n}\n\nimpl HttpRange {\n    /// Parses Range HTTP header string as per RFC 2616.\n    ///","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/actix/actix-web/blob/4d435abc281842f3cbee165b6cde739e001d3a25/actix-files/src/range.rs#L11-L47","documentation":"Returned by HttpRange::parse (range.rs:50) when the Range request header fails the bytes= grammar and the underlying http_range crate reports InvalidRange. In actix-files, NamedFile::into_response calls HttpRange::parse on the Range header (named.rs:609) and, on error, sets Content-Range and responds with 416 Range Not Satisfiable. It means the client sent a malformed range specifier such as bytes=foo or bytes=A-Z rather than a valid bytes=start-end expression.","triggerScenarios":"A client sends Range: bytes=5-Z, bytes=foo, bytes=7 (incomplete single value), bytes=0x01-0x02, or bytes=A- . The test suite in range.rs:75-92 enumerates these as rejected inputs.","commonSituations":"Hand-crafted curl commands with a typo in the Range header; custom download managers or media players emitting non-standard specifiers; an intermediate proxy rewriting the header into an invalid form.","solutions":["Send a syntactically valid range like bytes=0-499, bytes=500- (open-ended), or bytes=-500 (suffix); or omit the Range header to get the whole file.","If you control the client, only use the bytes=start-end, bytes=start-, bytes=-suffix, or comma-separated combinations of those forms.","On the server side, actix-files already auto-responds 416; no change is needed unless you want custom 416 handling."],"exampleFix":"// before\ncurl -H \"Range: bytes=5-Z\" http://host/file\n\n// after\ncurl -H \"Range: bytes=0-499\" http://host/file","handlingStrategy":"validation","validationCode":"// Validate a Range header before relying on it (client side)\nfn valid_range(h: &str) -> bool {\n    let s = h.strip_prefix(\"bytes=\").unwrap_or(h);\n    !s.is_empty() && s.split(',').all(|p| {\n        let p = p.trim();\n        match p.split_once('-') {\n            Some((a, b)) =>\n                (a.is_empty() || a.chars().all(|c| c.is_ascii_digit()))\n                && (b.is_empty() || b.chars().all(|c| c.is_ascii_digit())),\n            None => false,\n        }\n    })\n}","typeGuard":null,"tryCatchPattern":"// Server: actix-files already turns this into a 416; for custom serving:\nmatch actix_files::range::HttpRange::parse(range_header, file_len) {\n    Ok(ranges) => { /* serve partial content */ }\n    Err(_) => response.status(StatusCode::RANGE_NOT_SATISFIABLE).finish(),\n}","preventionTips":["Always emit ranges as bytes=start-end with decimal digits only.","Prefer a mature HTTP client over hand-built Range headers.","Log and discard 416s client-side then fall back to a full GET."],"tags":["http","range-header","actix-files","client-error"],"backgroundTag":null,"analyzedSha":"4d435abc281842f3cbee165b6cde739e001d3a25","analyzedAt":"2026-08-09T01:01:40.926Z","contentChangedAt":"2026-08-09T01:01:40.926Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}