{"record":{"id":"54c13569c78d1532","repo":"hashicorp/nomad","slug":"couldn-t-create-destination-file-v-w","errorCode":null,"errorMessage":"Couldn't create destination file %v: %w","messagePattern":"Couldn't create destination file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocdir/alloc_dir.go","lineNumber":574,"sourceCode":"\n// getFileWatcher returns a FileWatcher for the given path.\nfunc getFileWatcher(path string) watch.FileWatcher {\n\treturn watch.NewPollingFileWatcher(path)\n}\n\n// fileCopy from src to dst setting the permissions and owner (if uid & gid are\n// both greater than 0)\nfunc fileCopy(src, dst string, uid, gid int, perm os.FileMode) error {\n\t// Do a simple copy.\n\tsrcFile, err := os.Open(src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't open src file %v: %w\", src, err)\n\t}\n\tdefer srcFile.Close()\n\n\tdstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, perm)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't create destination file %v: %w\", dst, err)\n\t}\n\tdefer dstFile.Close()\n\n\tif _, err := io.Copy(dstFile, srcFile); err != nil {\n\t\treturn fmt.Errorf(\"Couldn't copy %q to %q: %w\", src, dst, err)\n\t}\n\n\tif uid != idUnsupported && gid != idUnsupported {\n\t\tif err := dstFile.Chown(uid, gid); err != nil {\n\t\t\treturn fmt.Errorf(\"Couldn't copy %q to %q: %w\", src, dst, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// pathExists is a helper function to check if the path exists.\nfunc pathExists(path string) bool {","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocdir/alloc_dir.go#L556-L592","documentation":"fileCopy() creates the destination with os.OpenFile(dst, O_WRONLY|O_CREATE, perm). Failure is wrapped as \"Couldn't create destination file\". This means the copy target could not be created or opened for writing in the alloc/task dir tree.","triggerScenarios":"Calling linkOrCopy/fileCopy where the destination path's parent does not exist, the destination is unwritable (permission denied), the disk is full, or the destination path is a directory.","commonSituations":"Task dir tree partially created before copy; ENOSPC on a full client volume; destination name collides with an existing directory; permission mismatch after user: changes in task config.","solutions":["Ensure the destination's parent directory exists and is created with correct permissions first","Check disk space (ENOSPC) and free space on the client volume","Verify the destination path does not collide with an existing directory","Run os.Chown/os.Chmod on the created file as needed (fileCopy only sets perm at create)"],"exampleFix":"// before\nfileCopy(src, \"task/web/no/such/dir/f\", uid, gid, perm)\n// after\nos.MkdirAll(filepath.Dir(dst), 0755)\nfileCopy(src, dst, uid, gid, perm)","handlingStrategy":"try-catch","validationCode":"parent := filepath.Dir(dst)\nif err := os.MkdirAll(parent, 0o755); err != nil {\n    return fmt.Errorf(\"cannot create dst parent: %w\", err)\n}\nif fi, err := os.Stat(dst); err == nil && fi.IsDir() {\n    return fmt.Errorf(\"dst is a directory: %q\", dst)\n}","typeGuard":null,"tryCatchPattern":"if err := linkOrCopy(src, dst, uid, gid, perm); err != nil {\n    if errors.Is(err, syscall.ENOSPC) {\n        // free disk space or move data_dir, then retry\n    }\n    return err\n}","preventionTips":["Create destination parent dirs before copying","Monitor client volume free space (guard against ENOSPC)","Ensure destination names don't collide with directories","Apply chown/chmod after copy when uid/gid/perm matter"],"tags":["filesystem","file-copy","permissions"],"backgroundTag":"file-create-failed","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"}