{"record":{"id":"e7fd20a26d2c21fe","repo":"nats-io/nats-server","slug":"could-not-create-message-storage-directory-v","errorCode":null,"errorMessage":"could not create message storage directory - %v","messagePattern":"could not create message storage directory - (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/filestore.go","lineNumber":488,"sourceCode":"\n\t// Register with access time service.\n\tats.Register()\n\n\t// If we error before completion make sure to cleanup.\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tats.Unregister()\n\t\t}\n\t}()\n\n\t// Set flush in place to AsyncFlush which by default is false.\n\tfs.fip = !fcfg.AsyncFlush\n\n\t// Check if this is a new setup.\n\tmdir := filepath.Join(fcfg.StoreDir, msgDir)\n\todir := filepath.Join(fcfg.StoreDir, consumerDir)\n\tif err := os.MkdirAll(mdir, defaultDirPerms); err != nil {\n\t\treturn nil, fmt.Errorf(\"could not create message storage directory - %v\", err)\n\t}\n\tif err := os.MkdirAll(odir, defaultDirPerms); err != nil {\n\t\treturn nil, fmt.Errorf(\"could not create consumer storage directory - %v\", err)\n\t}\n\n\t// Create highway hash for message blocks. Use sha256 of directory as key.\n\tkey := sha256.Sum256([]byte(cfg.Name))\n\tfs.hh, err = highwayhash.NewDigest64(key[:])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not create hash: %v\", err)\n\t}\n\n\tkeyFile := filepath.Join(fs.fcfg.StoreDir, JetStreamMetaFileKey)\n\t_, err = os.Stat(keyFile)\n\t// Either the file should exist (err=nil), or it shouldn't. Any other error is reported.\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn nil, err\n\t}","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L470-L506","documentation":"After the base StoreDir checks pass, the file store creates the per-stream messages subdirectory (filepath.Join(StoreDir, msgDir)); os.MkdirAll failure is wrapped with the OS error. This happens later in newFileStoreWithCreatedAndMode, typically due to permissions or a filesystem error inside an existing directory.","triggerScenarios":"os.MkdirAll(mdir, defaultDirPerms) fails when creating the 'msgs' directory inside StoreDir (server/filestore.go:488).","commonSituations":"StoreDir writable but on a full filesystem; SELinux/AppArmor blocking nested creation; a file named like the msg subdirectory already exists; racing cleanup removed StoreDir mid-setup.","solutions":["Inspect the wrapped %v OS error for the exact cause","Ensure StoreDir is writable by the server user (chown/chmod)","Check for a regular file occupying the expected subdirectory path and remove it","Check disk space and security policies (SELinux/AppArmor) on the volume"],"exampleFix":"// before\n// $ ls /data/jetstream/my-stream/ => msgs (a file)\n// after\n// $ rm /data/jetstream/my-stream/msgs\n// server restarts and creates msgs/ directory","handlingStrategy":"try-catch","validationCode":"if err := os.MkdirAll(filepath.Join(storeDir, \"msgs\"), 0o755); err != nil {\n    return fmt.Errorf(\"msgs dir pre-check failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := startStream(); err != nil {\n    if strings.Contains(err.Error(), \"could not create message storage directory\") {\n        // inspect wrapped OS error, fix perms/space, then restart\n    }\n}","preventionTips":["Check disk space and permissions on the store dir before creating streams","Watch for files colliding with the msgs directory name","Review SELinux/AppArmor denials if perms look correct"],"tags":["jetstream","filesystem","permissions","go"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}