nats-io/nats-server · error
could not create snapshots directory - %v
Error message
could not create snapshots directory - %v
What it means
When creating the raft node, NATS ensures <store_dir>/snapshots exists using os.MkdirAll; failure triggers shutdown of the node and this error. It means the server could not create the snapshots directory (or a parent component) on disk.
Source
Thrown at server/raft.go:558
// the error upwards, otherwise we can complete recovery but have only
// a partial view of the world.
n.shutdown()
return nil, err
}
// We may have restored the peer state from the
// snapshot above. If not, we restore peers from
// the peer state file.
if len(n.peers) == 0 {
if err := restorePeerState(n); err != nil {
return nil, err
}
}
// Make sure that the snapshots directory exists.
if err := os.MkdirAll(filepath.Join(n.sd, snapshotsDir), defaultDirPerms); err != nil {
n.shutdown()
return nil, fmt.Errorf("could not create snapshots directory - %v", err)
}
truncateAndErr := func(index uint64) {
if err := n.wal.Truncate(index); err != nil {
n.setWriteErr(err)
}
}
// Retrieve the stream state from the WAL. If there are pending append
// entries that were committed but not applied before we last shut down,
// we will try to replay them and process them here.
var state StreamState
n.wal.FastState(&state)
n.bytes = state.Bytes
if state.Msgs > 0 {
n.debug("Replaying state of %d entries", state.Msgs)
View on GitHub (pinned to 3a66a489d2)
Solutions
- Inspect the wrapped %v error for the exact os cause (EACCES/ENOSPC/ENOTDIR).
- Remove any file occupying the snapshots path, or fix permissions/ownership of the store directory.
- Remount the store volume writable or relocate store_dir to writable storage.
- Ensure the server runs as a user with write access to the JetStream store root.
Example fix
// before: a file blocks the dir # file /data/js/snapshots /data/js/snapshots: ASCII text // after rm /data/js/snapshots && mkdir -p /data/js/snapshots
Defensive patterns
Strategy: validation
Validate before calling
snapDir := filepath.Join(storeDir, "snapshots")
if info, err := os.Stat(snapDir); err == nil && !info.IsDir() {
return fmt.Errorf("%q is a file, blocking snapshots dir", snapDir)
}
if err := os.MkdirAll(snapDir, 0750); err != nil {
return err
} Prevention
- Pre-create store_dir and store_dir/snapshots with correct ownership in provisioning.
- Never store files named 'snapshots' inside the raft store directory.
- Keep store volumes writable and monitor capacity.
When it happens
Trigger: os.MkdirAll(filepath.Join(n.sd, snapshotsDir), defaultDirPerms) returns an error: parent path is a file, permission denied on parent, read-only mount, or disk full.
Common situations: JetStream store directory contains a file named 'snapshots', store path on a read-only container volume, or partially-migrated store directories with wrong ownership.
Related errors
- raft: could not create storage directory - %v
- stream assignment or group missing
- group node missing
- stream node missing
- cluster node skew detected
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c19cd68c9f4efd68.
Report an issue: GitHub.