rust-lang/rust · critical
dep node {prev_index:?} is unexpectedly red
Error message
dep node {prev_index:?} is unexpectedly red What it means
ICE in Encoder::send_and_color (compiler/rustc_middle/src/dep_graph/serialized.rs:962). When re-encoding a node that existed in the previous graph, the code calls colors.try_set_color(prev_index, ...) and expects Success or AlreadyGreen; AlreadyRed is treated as a bug because the caller already decided this node is green (is_green == true) but the color map says it is red. It indicates an inconsistency between the marking pass and the encoding pass, often a race during parallel red-green marking.
Source
Thrown at compiler/rustc_middle/src/dep_graph/serialized.rs:962
colors: &DepNodeColorMap,
node: DepNode,
value_fingerprint: Fingerprint,
edges: &[DepNodeIndex],
is_green: bool,
) -> DepNodeIndex {
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
let node = NodeInfo { node, value_fingerprint, edges };
let mut local = self.status.local.borrow_mut();
let index = self.status.next_index(&mut *local);
let color = if is_green { DesiredColor::Green { index } } else { DesiredColor::Red };
// Use `try_set_color` to avoid racing when `send_promoted` is called concurrently
// on the same index.
match colors.try_set_color(prev_index, color) {
TrySetColorResult::Success => {}
TrySetColorResult::AlreadyRed => panic!("dep node {prev_index:?} is unexpectedly red"),
TrySetColorResult::AlreadyGreen { index } => return index,
}
self.status.bump_index(&mut *local);
self.status.encode_node(index, &node, &self.retained_graph, &mut *local);
index
}
/// Encodes a node that was promoted from the previous graph. It reads the information directly
/// from the previous dep graph and expects all edges to already have a new dep node index
/// assigned.
///
/// Tries to mark the dep node green, and returns Some if it is now green,
/// or None if had already been concurrently marked red.
#[inline]
pub(crate) fn send_promoted(
&self,
prev_index: SerializedDepNodeIndex,View on GitHub (pinned to 22057b88b0)
Solutions
- Clear the incremental cache (target/**/incremental) and rebuild; the previous-session colors are the most likely source of the inconsistency.
- Run a clean build with -C incremental=no to confirm the ICE disappears without incremental compilation.
- If it reproduces on a clean build, report to the rustc team as a threading/race bug in DepNodeColorMap, including the prev_index from the message and the parallelism level.
Defensive patterns
Strategy: retry
Validate before calling
// "dep node is unexpectedly red" is an incremental consistency
// verification failure. No pre-call check exists; mitigate by
// detecting a stale/corrupt cache and clearing it.
fn cache_looks_stale(target: &std::path::Path) -> bool {
let inc = target.join("incremental");
// Heuristic: incremental dir exists but was touched before the
// toolchain last changed.
if let Ok(meta) = std::fs::metadata(&inc) {
if let Ok(mtime) = meta.modified() {
return mtime < toolchain_install_time();
}
}
false
} Try / catch
// Retry once after a cache wipe when this panic surfaces during
// incremental verification.
use std::panic::{catch_unwind, AssertUnwindSafe};
match catch_unwind(AssertUnwindSafe(|| compile_with_incremental(tcx))) {
Ok(()) => {}
Err(_) => {
std::fs::remove_dir_all("target/debug/incremental").ok();
compile_without_incremental(tcx);
}
} Prevention
- Drop the -Z incremental-verify-ich flag if it triggers false positives on your nightly
- Keep a single toolchain per target directory; do not cross-compile with mismatched nightlies
- Run cargo clean after major dependency or toolchain upgrades
- Disable incremental compilation for long-running CI pipelines that may observe cache drift
When it happens
Trigger: try_set_color returns AlreadyRed while send_and_color was called with is_green=true. Typically happens under parallel query evaluation where two threads race to color the same SerializedDepNodeIndex and one marks it red (re-execute) while the other tries to mark it green (re-use).
Common situations: High-core / heavily parallel rustc builds stressing the red-green algorithm; races introduced by a refactor of DepNodeColorMap; corrupt previous-session colors loaded from a damaged incremental cache.
Related errors
- Error: trying to record dependency on DepNode {dep_node} in
- Error: A dep graph node ({kind:?}) does not have an unique i
- RUST_FORBID_DEP_GRAPH_EDGE invalid: {}
- counting sort fills every slot of a kind's range
- unsupported integer: {self:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/6338827037f6de60.json.
Report an issue: GitHub.