rust-lang/rust · critical

decode error: {e}

Error message

decode error: {e}

What it means

When decoding rmeta, `DefPathHashMapRef::decode` reads a length-prefixed byte slice and reconstructs an `odht::HashTable` via `from_raw_bytes`. If reconstruction fails, it panics with "decode error: {e}". This means the def-path-hash map bytes in the `.rmeta`/incremental metadata are structurally invalid or were produced by an incompatible encoder version.

Source

Thrown at compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs:56

                panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization")
            }
        }
    }
}

impl<'a> Decodable<BlobDecodeContext<'a>> for DefPathHashMapRef<'static> {
    fn decode(d: &mut BlobDecodeContext<'a>) -> DefPathHashMapRef<'static> {
        let len = d.read_usize();
        let pos = d.position();
        let o = d.blob().bytes().clone().slice(|blob| &blob[pos..pos + len]);

        // Although we already have the data we need via the `OwnedSlice`, we still need
        // to advance the `DecodeContext`'s position so it's in a valid state after
        // the method. We use `read_raw_bytes()` for that.
        let _ = d.read_raw_bytes(len);

        let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
            panic!("decode error: {e}");
        });
        DefPathHashMapRef::OwnedFromMetadata(inner)
    }
}

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Run `cargo clean` (or remove `target/` and any `incremental` dir) to discard stale/corrupt metadata and rebuild.
  2. Rebuild all dependencies from source with the current toolchain so `.rmeta` files match the decoder.
  3. If it persists, check for disk/NFS corruption and verify the odht/rustc_abi versions are consistent across the dependency graph; report as a rustc ICE with the backtrace if metadata is freshly produced.

Example fix

// no source fix; this is a metadata-corruption / version-mismatch panic.
// recover with:
//   cargo clean
//   cargo build
Defensive patterns

Strategy: try-catch

Validate before calling

// This is a runtime decode error from reading an `.rmeta` file's
// DefPathHashMap. You cannot fully prevent it (the file may be corrupt or
// written by a mismatched compiler), but you CAN pre-validate before decoding:
use std::fs;
use std::path::Path;

fn preflight_rmeta(path: &Path) -> Result<(), String> {
    let meta = fs::metadata(path)
        .map_err(|e| format!("rmeta missing: {e}"))?;
    if meta.len() < 8 {
        return Err("rmeta truncated (< 8 bytes)".into());
    }
    // Optionally check the file header magic / rustc version tag your crate
    // embeds, so you never hand an incompatible blob to the decoder.
    Ok(())
}

// Call preflight_rmeta() before invoking the decoder.

Type guard

// Narrow on a successful decode result rather than catching the panic.
enum DecodeOutcome<T> {
    Ok(T),
    Corrupt(String),
}

fn safe_decode<T: Decode>(bytes: &[u8]) -> DecodeOutcome<T> {
    match Decoder::read(bytes) {
        Ok(v)  => DecodeOutcome::Ok(v),
        Err(e) => DecodeOutcome::Corrupt(format!("decode error: {e}")),
    }
}

Try / catch

// The decoder returns Result; never unwrap it on untrusted .rmeta.
match DefPathHashMap::decode(&mut decoder, &tcx) {
    Ok(map) => use_map(map),
    Err(e) => {
        // Treat the crate as unreadable: drop it from the dependency graph,
        // log the file path + compiler version that produced it, and surface
        // a user-actionable message ('rebuild dependency X').
        tracing::error!(
            rmeta = %path.display(),
            error = %e,
            "def_path_hash_map decode failed; crate is corrupt or version-mismatched"
        );
        mark_crate_unusable(&path);
    }
 }

Prevention

When it happens

Trigger: Loading a crate's metadata (compiling against a dependency, or resuming incremental compilation) where `odht::HashTable::from_raw_bytes` returns `Err` — e.g. wrong magic/version header, truncated or zero-length blob, or a layout mismatch from an odht version change.

Common situations: Switching nightly compiler versions (or odht crate versions) without clearing `target/` incremental caches. Corrupt or partially-written `.rmeta` from a killed/interrupted build, disk-full, or NFS quirks. Mixing metadata produced by a cross-compiled toolchain with a different endianness/word-size assumption.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/8e2578d915323632.json. Report an issue: GitHub.