{"record":{"id":"3f7ccd9c52b4d60d","repo":"stalwartlabs/stalwart","slug":"invalid-utf-8","errorCode":null,"errorMessage":"Invalid UTF-8","messagePattern":"Invalid UTF-8","errorType":"exception","errorClass":"io::Error(InvalidData)","httpStatus":null,"severity":"error","filePath":"crates/jmap/src/registry/mapping/log.rs","lineNumber":507,"sourceCode":"    /// Create a new `RawRevLines` struct from a Reader`.\n    /// Internal buffering for iteration will use `cap` bytes at a time.\n    pub fn with_capacity(cap: usize, reader: R) -> RevLines<R> {\n        RevLines(RawRevLines::with_capacity(cap, reader))\n    }\n}\n\nimpl<R: Read + Seek> Iterator for RevLines<R> {\n    type Item = Result<String, std::io::Error>;\n\n    fn next(&mut self) -> Option<Result<String, std::io::Error>> {\n        let line = match self.0.next_line().transpose()? {\n            Ok(line) => line,\n            Err(error) => return Some(Err(error)),\n        };\n\n        Some(\n            String::from_utf8(line)\n                .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, \"Invalid UTF-8\")),\n        )\n    }\n}\n","sourceCodeStart":489,"sourceCodeEnd":511,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/jmap/src/registry/mapping/log.rs#L489-L511","documentation":"The JMAP log reader (`next` on a line iterator) reads raw bytes per line and converts them with String::from_utf8; any non-UTF-8 bytes produce this std::io::Error with kind InvalidData and message 'Invalid UTF-8'. It surfaces as the yielded item of the log-line iterator, i.e. the log file contains bytes that are not valid UTF-8.","triggerScenarios":"Iterating log lines via the mapping/log.rs reader when a line contains invalid UTF-8 — e.g. binary data, partially-written multibyte characters split by truncation/rotation, or a log written in a non-UTF-8 encoding (Latin-1, GBK).","commonSituations":"Log files corrupted by truncation mid-multibyte-character during rotation; logs produced by processes emitting binary output; environment locale producing non-UTF-8 output redirected into the log; partially flushed writes on crash.","solutions":["Locate the offending log file and inspect it with `file` / `iconv -f utf-8 -t utf-8` to find invalid byte sequences.","Re-encode the log to UTF-8 (e.g. `iconv -f latin1 -t utf-8`) if a non-UTF-8 encoding was used.","Trim/repair truncated lines (usually at file tail) or regenerate the log.","If you control the writer, ensure it writes UTF-8 and flushes whole lines atomically (or use from_utf8_lossy semantics when reading)."],"exampleFix":"// before\nString::from_utf8(line).map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, \"Invalid UTF-8\"))\n// after (caller-side lossy handling)\nlet text = String::from_utf8_lossy(&line);\nOk(text.into_owned())","handlingStrategy":"fallback","validationCode":"// check a log file for invalid UTF-8 before reading\nstd::fs::read(path).map(|bytes| String::from_utf8(bytes).is_ok())","typeGuard":null,"tryCatchPattern":"for line in log_lines {\n    match line {\n        Ok(text) => process(&text),\n        Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n            tracing::warn!(\"skipping non-UTF-8 log line: {e}\");\n        }\n        Err(e) => return Err(e.into()),\n    }\n}","preventionTips":["Ensure log writers emit UTF-8 and flush whole lines atomically.","Re-encode legacy logs (iconv) before ingesting them.","Treat log tails (partial writes from rotation/crash) with lossy decoding or truncation."],"tags":["encoding","utf-8","io","logs"],"backgroundTag":"invalid-argument-format","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}