{"record":{"id":"40aef83ebfb68a34","repo":"hashicorp/nomad","slug":"failed-to-create-wal-directory-w","errorCode":null,"errorMessage":"failed to create WAL directory: %w","messagePattern":"failed to create WAL directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/raftutil/migrate.go","lineNumber":91,"sourceCode":"\t}\n\tdefer os.Remove(markerPath) // Clean up marker on completion or failure.\n\n\t// Open the source BoltDB store.\n\tsrc, err := raftboltdb.New(raftboltdb.Options{\n\t\tPath: boltPath,\n\t\tBoltOptions: &bbolt.Options{\n\t\t\tTimeout: 5 * time.Second,\n\t\t},\n\t\tMsgpackUseNewTimeFormat: true,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open BoltDB store: %w\", err)\n\t}\n\n\t// Create the destination WAL store.\n\tif err := os.MkdirAll(walDir, 0o700); err != nil {\n\t\tsrc.Close()\n\t\treturn fmt.Errorf(\"failed to create WAL directory: %w\", err)\n\t}\n\n\tdst, err := raftwal.Open(walDir)\n\tif err != nil {\n\t\tsrc.Close()\n\t\tcleanupWAL(walDir)\n\t\treturn fmt.Errorf(\"failed to open WAL store: %w\", err)\n\t}\n\n\t// Copy logs.\n\tlogProgress := make(chan string, 64)\n\twg.Add(1)\n\tgo drainProgress(logProgress, progress, &wg)\n\tif err := migrate.CopyLogs(ctx, dst, src, migrateBatchBytes, logProgress); err != nil {\n\t\tdst.Close()\n\t\tsrc.Close()\n\t\tcleanupWAL(walDir)\n\t\treturn fmt.Errorf(\"failed to copy logs: %w\", err)","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/raftutil/migrate.go#L73-L109","documentation":"MigrateToWAL creates the destination WAL directory at <raftDir>/wal via os.MkdirAll after opening the source BoltDB store. This error wraps the OS error when that directory cannot be created. Migration aborts, the BoltDB store is closed, and the original raft.db is left untouched, so the operation is safe to retry.","triggerScenarios":"os.MkdirAll(walDir, 0o700) returns an error: the parent raft directory is read-only or not writable by the process user, a file (not directory) named 'wal' exists at the target path despite preflight, the path is too long, or an I/O error occurs on the underlying filesystem.","commonSituations":"Running the Nomad server or migration under a service account that lacks write access to the raft data dir; raft dir on a read-only mounted volume (e.g. container image or read-only PVC); a stale 'wal' file left by a previous failed run; SELinux/AppArmor denials.","solutions":["Check that the process user has write permission on the raft directory (ls -ld <raftDir>; chown/chmod as needed).","Verify no non-directory file named 'wal' exists at <raftDir>/wal and remove/rename it.","Confirm the raft volume is mounted read-write (mount | grep <raftDir>; remount or fix container volume config).","Fix the wrapped OS error indicated in the %w suffix (e.g. ENOSPC, ENAMETOOLONG) and re-run MigrateToWAL."],"exampleFix":"// before (migrating inside a container with read-only data volume)\nvolumes:\n  - /opt/nomad/data:ro\n// after\nvolumes:\n  - /opt/nomad/data:/opt/nomad/data","handlingStrategy":"validation","validationCode":"walDir := filepath.Join(raftDir, \"wal\")\nif fi, err := os.Stat(walDir); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory; remove it first\", walDir)\n}\nif err := unix.Access(raftDir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"no write access to %s: %w\", raftDir, err)\n}","typeGuard":null,"tryCatchPattern":"err := raftutil.MigrateToWAL(ctx, raftDir, progress)\nvar pathErr *os.PathError\nif errors.As(err, &pathErr) && errors.Is(pathErr.Err, syscall.EACCES) {\n    // fix permissions or run as another user\n}","preventionTips":["Run the migration as the same OS user that owns the raft data directory.","Keep raft data on a read-write local volume, never a read-only mount or NFS.","Check for stray 'wal' files before migrating.","Keep paths short to avoid ENAMETOOLONG."],"tags":["filesystem","permissions","migration","raft-wal"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}