rust-lang/rust · critical

Error: A dep graph node ({kind:?}) does not have an unique i

Error message

Error: A dep graph node ({kind:?}) does not have an unique index. Running a clean build on a nightly compiler with `-Z incremental-verify-ich` can help narrow down the issue for reporting. A clean build may also work around the issue.
DepNode: {node:?}

What it means

ICE raised while building the SerializedDepGraph reverse index (compiler/rustc_middle/src/dep_graph/serialized.rs:196) when two distinct DepNodes of the same DepKind produce the same key_fingerprint. The exception is DepKind::SideEffect, which is allowed to share fingerprints. For all other kinds, fingerprint uniqueness is a core invariant; a collision means hashing is non-deterministic or the graph is corrupt. The message recommends -Z incremental-verify-ich to localize the fault.

Source

Thrown at compiler/rustc_middle/src/dep_graph/serialized.rs:196

        nodes_by_kind: &[Option<SerializedDepNodeIndex>],
        profiler: &Option<SelfProfilerRef>,
    ) -> &UnhashMap<PackedFingerprint, SerializedDepNodeIndex> {
        self.map.get_or_init(|| {
            let _prof_timer = profiler
                .as_ref()
                .map(|p| p.generic_activity("incr_comp_load_dep_graph_reverse_index"));
            let range = (self.start as usize)..(self.start as usize + self.len as usize);
            let mut map =
                UnhashMap::with_capacity_and_hasher(self.len as usize, Default::default());
            for &idx in &nodes_by_kind[range] {
                let idx = idx.expect("counting sort fills every slot of a kind's range");
                let node = nodes[idx];
                debug_assert_eq!(node.kind, kind);
                if map.insert(node.key_fingerprint, idx).is_some()
                    // Side effect nodes can legitimately share a fingerprint.
                    && node.kind != DepKind::SideEffect
                {
                    panic!(
                        "Error: A dep graph node ({kind:?}) does not have an unique index. \
                         Running a clean build on a nightly compiler with \
                         `-Z incremental-verify-ich` can help narrow down the issue for reporting. \
                         A clean build may also work around the issue.\n
                         DepNode: {node:?}"
                    )
                }
            }
            map
        })
    }
}

impl SerializedDepGraph {
    #[inline]
    pub fn edge_targets_from(
        &self,
        source: SerializedDepNodeIndex,

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Do a clean build (cargo clean) — this is the documented workaround in the panic message itself and resolves most transient collisions.
  2. Rebuild on a recent nightly with -Z incremental-verify-ich to catch the unstable fingerprint as it is produced and narrow down which query/DepNode is at fault.
  3. Check for and disable any non-default hashing/randomization knobs (RUSTC_FORCE_INCREMENTAL, custom RUSTFLAGS touching hashing).
  4. If reproducible after a clean build, file an ICE report against rustc with the DepNode printed in the message.

Example fix

# before
cargo build  # reusing a stale/cross-version incremental cache

# after
cargo clean && cargo +nightly build -Z incremental-verify-ich
Defensive patterns

Strategy: retry

Validate before calling

// The message itself recommends a clean build on nightly with
// -Z incremental-verify-ich. Pre-flight: wipe the cache and set
// the verification flag.
fn configure_verify_ich(cmd: &mut std::process::Command) {
    let _ = std::fs::remove_dir_all("target/debug/incremental");
    cmd.args(["-Z", "incremental-verify-ich"]);
}

Try / catch

// Catch the panic, capture the offending DepNode from the message
// for the bug report, then retry with a clean incremental cache.
use std::panic::{catch_unwind, AssertUnwindSafe};

let outcome = catch_unwind(AssertUnwindSafe(|| run_compiler_pass(tcx)));
if outcome.is_err() {
    let _ = std::fs::remove_dir_all("target/debug/incremental");
    // retry once; if it reproduces, file an ICE report with the DepNode details
    run_compiler_pass(tcx);
}

Prevention

When it happens

Trigger: Two different DepNodes of the same kind hash to the same PackedFingerprint during fingerprint_map construction, which happens lazily on first lookup of that kind. Caused by a non-stable hasher seed, a bug in the DepNode's StableHash impl, or a corrupt serialized graph that re-encodes two nodes with the same key.

Common situations: Bisecting rustc nightlies where StableHash of a query input changed; third-party tools that hand-craft query inputs; hardware/disk corruption silently flipping bits in the cached graph; running with RUSTC_RANDOMIZE_LAYOUT or unstable hashing knobs enabled.

Related errors


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