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

  1. Inspect the wrapped %v error for the exact os cause (EACCES/ENOSPC/ENOTDIR).
  2. Remove any file occupying the snapshots path, or fix permissions/ownership of the store directory.
  3. Remount the store volume writable or relocate store_dir to writable storage.
  4. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/c19cd68c9f4efd68. Report an issue: GitHub.