{"record":{"id":"65ac0a0528a61327","repo":"nats-io/nats-server","slug":"storage-directory-is-not-a-directory","errorCode":null,"errorMessage":"storage directory is not a directory","messagePattern":"storage directory is not a directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/filestore.go","lineNumber":443,"sourceCode":"\t}\n\tif fcfg.CacheExpire == 0 {\n\t\tfcfg.CacheExpire = defaultCacheBufferExpiration\n\t}\n\tif fcfg.SubjectStateExpire == 0 {\n\t\tfcfg.SubjectStateExpire = defaultFssExpiration\n\t}\n\tif fcfg.SyncInterval == 0 {\n\t\tfcfg.SyncInterval = defaultSyncInterval\n\t}\n\tdios := fcfg.srv.diskIOSemaphore()\n\n\t// Check the directory\n\tif stat, err := os.Stat(fcfg.StoreDir); os.IsNotExist(err) {\n\t\tif err := os.MkdirAll(fcfg.StoreDir, defaultDirPerms); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"could not create storage directory - %v\", err)\n\t\t}\n\t} else if stat == nil || !stat.IsDir() {\n\t\treturn nil, fmt.Errorf(\"storage directory is not a directory\")\n\t}\n\ttmpfile, err := os.CreateTemp(fcfg.StoreDir, \"_test_\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"storage directory is not writable\")\n\t}\n\n\ttmpfile.Close()\n\tdios.acquire()\n\tos.Remove(tmpfile.Name())\n\tdios.release()\n\n\tfs = &fileStore{\n\t\tfcfg:       fcfg,\n\t\tdios:       dios,\n\t\tpsim:       stree.NewSubjectTree[psi](),\n\t\tbim:        make(map[uint32]*msgBlock),\n\t\tcfg:        FileStreamInfo{Created: created, StreamConfig: cfg},\n\t\tprf:        prf,","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L425-L461","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nstore_dir: \"/data/jetstream\" // exists as a regular file\n// after\n// $ mv /data/jetstream /data/jetstream.bak && mkdir -p /data/jetstream\nstore_dir: \"/data/jetstream\"","handlingStrategy":"validation","validationCode":"if fi, err := os.Stat(storeDir); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists but is not a directory\", storeDir)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["jetstream","filesystem","path","go"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}