nats-io/nats-server · critical
snapshot check detected %d bad messages
Error message
snapshot check detected %d bad messages
What it means
Raised when a snapshot consistency check completes but finds messages: the verification read (ld) contains bad messages, so the snapshot is rejected rather than producing a corrupt backup. The count of bad messages is included in the message. This indicates data problems in the stream's file storage rather than an API misuse.
Source
Thrown at server/filestore.go:12919
}
// Mark us as snapshotting
fs.sips += 1
fs.mu.Unlock()
if checkMsgs {
ld, err := fs.checkMsgs()
clearSips := func() {
fs.mu.Lock()
fs.sips--
fs.mu.Unlock()
}
if err != nil {
clearSips()
return nil, fmt.Errorf("snapshot check failed: %w", err)
}
if ld != nil && len(ld.Msgs) > 0 {
clearSips()
return nil, fmt.Errorf("snapshot check detected %d bad messages", len(ld.Msgs))
}
}
pr, pw := net.Pipe()
// Set a write deadline here to protect ourselves.
if deadline > 0 {
pw.SetWriteDeadline(time.Now().Add(deadline))
}
// We can add to our stream while snapshotting but not "user" delete anything.
var state StreamState
fs.FastState(&state)
// Stream in separate Go routine.
errCh := make(chan error, 1)
go fs.streamSnapshot(pw, includeConsumers, errCh)
View on GitHub (pinned to 3a66a489d2)
Solutions
- Treat the stream as suspect: validate/repair by restoring the stream from a known-good backup.
- Check server logs and the wrapped errors around this check for the specific bad sequences.
- Avoid copying live filestore directories; use proper snapshot/backup APIs.
- If corruption is hardware-driven, replace/repair storage and rebuild the stream.
Defensive patterns
Strategy: fallback
Try / catch
// Go: on bad-message detection, fall back to a known-good backup
if strings.Contains(err.Error(), "snapshot check detected") {
log.Printf("stream data integrity compromised: %v", err)
// restore stream from last good snapshot
} Prevention
- Only snapshot via official APIs, never copy live data files
- Schedule integrity checks on streams
- Retain multiple backup generations
- Investigate any prior crash or hardware errors on the storage host
When it happens
Trigger: Stream snapshot verification where the check read returns non-empty ld.Msgs after verifying snapshot consistency, meaning messages read back differ from what the snapshot state expects.
Common situations: Streams affected by prior disk corruption, crashed writes, or files tampered with/synced inconsistently (e.g. rsync of a live stream directory); running an older server on data written by a newer version.
Related errors
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c5ba65162f77a757.
Report an issue: GitHub.