nats-io/nats-server · error
failed to load block from disk: %w
Error message
failed to load block from disk: %w
What it means
Wraps any error from mb.loadBlock(nil) that occurs while truncating the last message block: if the block is compressed and/or encrypted, it must be fully loaded into memory first. This error means the block file could not be read/validated from disk (IO error, checksum failure, or underlying corruption like 'sanity check failed').
Source
Thrown at server/filestore.go:6878
if rl > mb.bytes {
rl = mb.bytes
}
mb.bytes -= rl
mb.rbytes -= rl
// For return accounting.
purged++
bytes += uint64(rl)
}
}
}
// If the block is compressed/encrypted then we have to load it into memory
// and decompress/decrypt it, truncate it and then write it back out.
// Otherwise, truncate the file itself and close the descriptor.
if mb.cmp != NoCompression || mb.bek != nil {
buf, err := mb.loadBlock(nil)
if err != nil {
return 0, 0, fmt.Errorf("failed to load block from disk: %w", err)
}
if err = mb.encryptOrDecryptIfNeeded(buf); err != nil {
return 0, 0, err
}
if buf, err = mb.decompressIfNeeded(buf); err != nil {
return 0, 0, fmt.Errorf("failed to decompress block: %w", err)
}
buf = buf[:eof]
copy(mb.lchk[0:], buf[len(buf)-checksumSize:])
// We did decompress but don't recompress the truncated buffer here since we're the last block
// and would otherwise have compressed data and allow to write uncompressed data in the same block.
if err = mb.atomicOverwriteFile(buf, false); err != nil {
return 0, 0, err
}
} else if mb.mfd != nil {
if err = mb.mfd.Truncate(eof); err != nil {
return 0, 0, err
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Inspect the wrapped cause (read error vs checksum vs sanity check) with debug logging
- Remove/reset the affected stream files so JetStream recreates them (accepting data loss for that stream)
- Restore the store directory from a consistent offline backup
- Run filesystem/disk health checks and replace failing hardware
Defensive patterns
Strategy: try-catch
Validate before calling
// Before trim/compact operations, verify store volume readability and space
if info, err := os.Stat(storeDir); err != nil || !info.IsDir() {
return fmt.Errorf("store dir unreadable: %v", err)
} Try / catch
// Go: inspect the wrapped cause of 'failed to load block from disk'
if _, _, err := truncateLastBlock(mb, eof); err != nil {
var ioErr *os.PathError
if errors.As(err, &ioErr) {
// OS-level read failure: check disk/filesystem
} else if strings.Contains(err.Error(), "sanity check") {
// corrupt block: restore backup or reset stream
}
return err
} Prevention
- Monitor disk health (SMART) on jetstream nodes
- Back up store directories only while stopped
- Avoid kill -9 and power loss on storage volumes
- Run fsck after unclean host shutdowns
When it happens
Trigger: Trimming/compacting the last block of a stream (truncateMsgs path) when the block has compression (mb.cmp != NoCompression) or encryption (mb.bek != nil) and loadBlock fails — unreadable file, bad checksum, corrupt record layout.
Common situations: Corrupt or truncated block files after crashes, failing disks, restored backups missing chunks, or read errors at the OS level (EIO).
Related errors
- failed to decompress block: %w
- Error creating msg block file: %v
- message overrun
- sanity check failed
- rebuildState for block %d failed: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/4e70dce13b591a3d.
Report an issue: GitHub.