nats-io/nats-server · critical
could not create storage streams directory - %v
Error message
could not create storage streams directory - %v
What it means
When initializing per-account JetStream storage, the server ensures the <storeDir>/streams directory exists, creating it with defaultDirPerms via os.MkdirAll. If the OS-level mkdir fails (permissions, path conflicts, full disk, not a directory), this error wraps the underlying OS error and aborts account stream storage setup.
Source
Thrown at server/jetstream.go:1292
s.Debugf("Enabled JetStream for account %q", a.Name)
if l, ok := limits[_EMPTY_]; ok {
s.Debugf(" Max Memory: %s", friendlyBytes(l.MaxMemory))
s.Debugf(" Max Storage: %s", friendlyBytes(l.MaxStore))
} else {
for t, l := range limits {
s.Debugf(" Tier: %s", t)
s.Debugf(" Max Memory: %s", friendlyBytes(l.MaxMemory))
s.Debugf(" Max Storage: %s", friendlyBytes(l.MaxStore))
}
}
// Clean up any old snapshots that were orphaned while staging.
os.RemoveAll(filepath.Join(js.config.StoreDir, snapStagingDir))
sdir := filepath.Join(jsa.storeDir, streamsDir)
if _, err := os.Stat(sdir); os.IsNotExist(err) {
if err := os.MkdirAll(sdir, defaultDirPerms); err != nil {
return fmt.Errorf("could not create storage streams directory - %v", err)
}
// Just need to make sure we can write to the directory.
// Remove the directory will create later if needed.
os.RemoveAll(sdir)
// when empty remove parent directory, which may have been created as well
os.Remove(jsa.storeDir)
} else {
// Restore any state here.
s.Debugf("Recovering JetStream state for account %q", a.Name)
}
// Remember if we should be encrypted and what cipher we think we should use.
encrypted := s.getOpts().JetStreamKey != _EMPTY_
sc := s.getOpts().JetStreamCipher
doConsumers := func(mset *stream, odir string) {
ofis, _ := os.ReadDir(odir)
if len(ofis) > 0 {View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the wrapped OS error (%v) to identify the exact filesystem cause.
- chown/chmod the jetstream store directory so the server process user can write (defaultDirPerms is typically 0750/0755).
- Ensure store_dir path exists, is a directory, and contains no file named 'streams'.
- Check disk space and that the filesystem is writable (not read-only mounted).
- Fix and restart the server; partially created empty dirs are cleaned up automatically.
Example fix
// before store_dir: "/nfs/readonly/jetstream" // after (and on host) store_dir: "/var/lib/nats/jetstream" # mkdir -p /var/lib/nats/jetstream && chown nats:nats /var/lib/nats/jetstream
Defensive patterns
Strategy: validation
Validate before calling
sd := storeDir
if fi, err := os.Stat(sd); err != nil || !fi.IsDir() {
return fmt.Errorf("store_dir %s missing or not a directory: %v", sd, err)
}
probe := filepath.Join(sd, ".write_probe")
if err := os.WriteFile(probe, []byte("ok"), 0600); err != nil {
return fmt.Errorf("store_dir not writable: %w", err)
}
os.Remove(probe) Prevention
- chown/chmod the jetstream store_dir for the server's runtime user before start
- Do not mount the store directory read-only in containers
- Monitor free disk space on the store volume
- Ensure no regular file named 'streams' exists in per-account store dirs
- Use `nats-server -t` and a smoke test start after changing store_dir
When it happens
Trigger: Starting a server with jetstream store_dir where os.MkdirAll(jsa.storeDir + '/streams') fails - e.g. permission denied on the store directory, store dir path is a file, read-only filesystem, or disk full.
Common situations: store_dir owned by another user (server run as different UID); container volume mounted read-only; leftover file named 'streams' in the store dir; NFS/permission issues after migrating store directories; full disk after large streams.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- could not create storage directory - %v
- storage directory is not writable
- could not create message storage directory - %v
- could not create consumer storage directory - %v
- could not create consumer directory - %v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/65f16fa16f79917a.
Report an issue: GitHub.