nats-io/nats-server · critical
storage directory is not writable
Error message
storage directory is not writable
What it means
As a writability check, the file store creates a temporary probe file via os.CreateTemp in StoreDir; failure means the directory exists but the process cannot write to it (permissions, read-only mount, disk full). The store aborts rather than risking data loss later.
Source
Thrown at server/filestore.go:447
if fcfg.SubjectStateExpire == 0 {
fcfg.SubjectStateExpire = defaultFssExpiration
}
if fcfg.SyncInterval == 0 {
fcfg.SyncInterval = defaultSyncInterval
}
dios := fcfg.srv.diskIOSemaphore()
// Check the directory
if stat, err := os.Stat(fcfg.StoreDir); os.IsNotExist(err) {
if err := os.MkdirAll(fcfg.StoreDir, defaultDirPerms); err != nil {
return nil, fmt.Errorf("could not create storage directory - %v", err)
}
} else if stat == nil || !stat.IsDir() {
return nil, fmt.Errorf("storage directory is not a directory")
}
tmpfile, err := os.CreateTemp(fcfg.StoreDir, "_test_")
if err != nil {
return nil, fmt.Errorf("storage directory is not writable")
}
tmpfile.Close()
dios.acquire()
os.Remove(tmpfile.Name())
dios.release()
fs = &fileStore{
fcfg: fcfg,
dios: dios,
psim: stree.NewSubjectTree[psi](),
bim: make(map[uint32]*msgBlock),
cfg: FileStreamInfo{Created: created, StreamConfig: cfg},
prf: prf,
oldprf: oldprf,
qch: make(chan struct{}),
fsld: make(chan struct{}),
srv: fcfg.srv,View on GitHub (pinned to 3a66a489d2)
Solutions
- Grant the server process user write permission on the directory (chown/chmod)
- Remount the volume read-write if mounted read-only
- Free disk space or resolve quota limits
- Point store_dir at a writable location
Example fix
// before // $ ls -ld /data/jetstream => drwxr-xr-x root root // after // $ sudo chown -R nats:nats /data/jetstream store_dir: "/data/jetstream" // now writable by the server user
Defensive patterns
Strategy: validation
Validate before calling
probe, err := os.CreateTemp(storeDir, "_probe_")
if err != nil {
return fmt.Errorf("store dir not writable: %w", err)
}
probe.Close()
os.Remove(probe.Name()) Try / catch
if _, err := os.CreateTemp(storeDir, "_probe_"); err != nil {
return fmt.Errorf("store dir not writable: %w", err)
} Prevention
- Chown the data directory to the server's runtime user
- Verify volumes are not mounted :ro
- Monitor free disk space and inodes
When it happens
Trigger: os.CreateTemp(fcfg.StoreDir, "_test_") returns an error during file store creation (server/filestore.go:447).
Common situations: Directory owned by another user (e.g. created by root, server runs as nats); Kubernetes/Docker volume mounted read-only; full disk or noexec/quota limits.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- could not create storage directory - %v
- could not create message storage directory - %v
- could not create consumer storage directory - %v
- storage directory is not a directory
- failed to write to temporary file: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/e4c2eaf0c904a694.
Report an issue: GitHub.