rust-lang/rust · error · anyhow::Error
unparsed bytes: 0x{:02x?}
Error message
unparsed bytes: 0x{:02x?} What it means
Raised by Parser::ensure_empty when, after consuming all expected fields of a coverage record, self.rest still contains trailing bytes. It is a structural integrity check: the parser's read sequence did not account for every byte in the input, meaning either an unknown extension field or a misparse occurred.
Source
Thrown at src/tools/coverage-dump/src/parser.rs:13
use anyhow::ensure;
pub(crate) struct Parser<'a> {
rest: &'a [u8],
}
impl<'a> Parser<'a> {
pub(crate) fn new(input: &'a [u8]) -> Self {
Self { rest: input }
}
pub(crate) fn ensure_empty(self) -> anyhow::Result<()> {
ensure!(self.rest.is_empty(), "unparsed bytes: 0x{:02x?}", self.rest);
Ok(())
}
pub(crate) fn read_n_bytes(&mut self, n: usize) -> anyhow::Result<&'a [u8]> {
ensure!(n <= self.rest.len());
let (bytes, rest) = self.rest.split_at(n);
self.rest = rest;
Ok(bytes)
}
pub(crate) fn read_uleb128_u32(&mut self) -> anyhow::Result<u32> {
self.read_uleb128_u64_and_convert()
}
pub(crate) fn read_uleb128_usize(&mut self) -> anyhow::Result<usize> {
self.read_uleb128_u64_and_convert()
}View on GitHub (pinned to 7088e4b63a)
Solutions
- Rebuild coverage-dump from the same commit as the rustc that emitted the coverage data.
- Inspect the leftover bytes (0x..) for a recognizable LLVM coverage record tag to identify the new field.
- Check rust-lang/rust for recent changes to coverage mapping versioning (CoverageMappingVersion).
- Re-generate the coverage data with a toolchain matching coverage-dump's expected format version.
Example fix
// before: bail on any leftover bytes
ensure!(self.rest.is_empty(), "unparsed bytes: 0x{:02x?}", self.rest);
// after: tolerate unknown trailing bytes with a warning when forward-compat is desired
if !self.rest.is_empty() {
tracing::warn!("unparsed {} trailing bytes: 0x{:02x?}", self.rest.len(), self.rest);
}
// (only do this if the format explicitly permits future extensions) Defensive patterns
Strategy: validation
Validate before calling
// If you feed coverage-dump programmatically, verify the format version header
// matches what your coverage-dump build expects before parsing:
if coverage_format_version(&bytes) != SUPPORTED_VERSION {
return Err(anyhow!("coverage format {} unsupported by this coverage-dump",
coverage_format_version(&bytes)));
} Type guard
null
Try / catch
match parser.ensure_empty() {
Ok(()) => Ok(parsed),
Err(e) => {
tracing::warn!("parser left trailing bytes; coverage format may be newer: {e}");
Ok(parsed) // only if forward-compat is acceptable for your use
}
} Prevention
- Keep coverage-dump at the same commit as the rustc that emitted the data.
- Add a coverage-format-version check before invoking the detailed parser.
- Treat unparsed-bytes warnings as a signal to upgrade, not noise.
When it happens
Trigger: Called at the end of parsing a coverage data structure (e.g. after reading all function records / counter expressions) when ensure_empty() is invoked on the Parser. Triggers when the LLVM coverage format version adds fields this coverage-dump does not know about, or when a preceding read_uleb128 under-read a length-prefixed region.
Common situations: Upgrading rustc/LLVM to a version that extended the coverage mapping format while coverage-dump is pinned to an older revision; manually crafted or fuzzed coverage inputs; a bug where a length field is read as u32 but the body is shorter, leaving leftover bytes.
Related errors
- unexpected base kind for gap region: {kind:?}
- unknown mapping kind: {raw_mapping_kind:#x}
- {e:?}
- llvm-readelf failed for binary {binary} with output {stdout}
- Build ID not found for binary {binary}
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/82740c326d9feb80.
Report an issue: GitHub.