nats-io/nats-server · critical
storage directory is not a directory
Error message
storage directory is not a directory
What it means
os.Stat on StoreDir succeeded (or returned a non-not-exist state) but the path is not a directory — either stat is nil unexpectedly or stat.IsDir() is false. This means StoreDir points to an existing regular file, symlink to a file, or another non-directory type.
Source
Thrown at server/filestore.go:443
}
if fcfg.CacheExpire == 0 {
fcfg.CacheExpire = defaultCacheBufferExpiration
}
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,View on GitHub (pinned to 3a66a489d2)
Solutions
- Inspect the path (ls -la <StoreDir>) and remove or rename the non-directory entry
- Recreate it as a directory (mkdir <StoreDir>) with correct ownership
- Correct StoreDir in the config if it points at the wrong path
Example fix
// before store_dir: "/data/jetstream" // exists as a regular file // after // $ mv /data/jetstream /data/jetstream.bak && mkdir -p /data/jetstream store_dir: "/data/jetstream"
Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(storeDir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists but is not a directory", storeDir)
} Prevention
- Check the store_dir path with ls -la before startup
- Avoid bind-mounting files where directories are expected
- Add a startup health check that verifies the path is a directory
When it happens
Trigger: os.Stat(fcfg.StoreDir) returns no not-exist error but stat.IsDir() is false when creating a file store (server/filestore.go:443), e.g. StoreDir is a regular file created by a previous misconfiguration.
Common situations: A config tool or script accidentally created a file at the StoreDir path; docker bind-mounting a file instead of a directory; stale artifact left where the data dir should be.
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
- failed to write to temporary file: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/65ac0a0528a61327.
Report an issue: GitHub.