zeroclaw-labs/zeroclaw · critical
prev_hash mismatch at line {} (sequence {}): expected {}, go
Error message
prev_hash mismatch at line {} (sequence {}): expected {}, got {} What it means
An entry's prev_hash does not equal the previous entry's entry_hash, so the hash-chain linkage is broken at that line. The chain proves each record hash-seals its predecessor; a mismatch means lines were inserted, removed, or reordered after the fact — the log has been spliced or corrupted.
Source
Thrown at crates/zeroclaw-runtime/src/security/audit.rs:483
let line = line?;
if line.trim().is_empty() {
continue;
}
let entry: AuditEvent = serde_json::from_str(&line)?;
// Check sequence continuity
if entry.sequence != expected_sequence {
bail!(
"sequence gap at line {}: expected {}, got {}",
line_idx + 1,
expected_sequence,
entry.sequence
);
}
// Check prev_hash linkage
if entry.prev_hash != expected_prev_hash {
bail!(
"prev_hash mismatch at line {} (sequence {}): expected {}, got {}",
line_idx + 1,
entry.sequence,
expected_prev_hash,
entry.prev_hash
);
}
// Recompute and verify entry_hash
let recomputed = compute_entry_hash(&entry.prev_hash, &entry);
if entry.entry_hash != recomputed {
bail!(
"entry_hash mismatch at line {} (sequence {}): expected {}, got {}",
line_idx + 1,
entry.sequence,
recomputed,
entry.entry_hash
);View on GitHub (pinned to 88bb9c8533)
Solutions
- Compare against the newest intact backup and restore it; quantify what changed since.
- Treat as a tamper event: quarantine the log, alert security, preserve the original file.
- If the cause is benign (merging logs), split back into the original per-daemon files and verify each separately.
- Prevent recurrence: single writer via endpoint lock, append-only permissions where possible.
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = audit.verify_chain() {
if e.to_string().contains("prev_hash mismatch") {
// splice/reorder detected: quarantine file, compare with last known-good backup, alert
}
} Prevention
- Never merge or reorder audit log files; keep per-daemon logs separate.
- Automate verification right after any backup/restore exercise.
- Restrict write access to the audit log to the daemon account only.
When it happens
Trigger: A forged line inserted into the middle of the log; two log segments from different runs concatenated out of order; lines deleted and neighbors not resealing (they never re-seal, hence detection); manual reorder during 'cleanup'.
Common situations: Tamper-evidence tests; merging audit logs from two daemon instances by accident; restoring an interleaved backup; text-editor saves that reorder or drop lines.
Related errors
- sequence gap at line {}: expected {}, got {}
- entry_hash mismatch at line {} (sequence {}): expected {}, g
- signature verification failed at line {} (sequence {}): sign
- purge_namespace not supported by this memory backend
- purge_session not supported by this memory backend
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/4b1b507657401476.
Report an issue: GitHub.