{"record":{"id":"d942b4983699073f","repo":"hashicorp/vagrant","slug":"you-have-attempted-to-export-the-same-nfs-host-pat","errorCode":null,"errorMessage":"You have attempted to export the same nfs host path at %{hostpath} with\ndifferent nfs permissions. Please pick one permission and reload your guest.","messagePattern":"You have attempted to export the same nfs host path at %(.+?) with\ndifferent nfs permissions\\. Please pick one permission and reload your guest\\.","errorType":"exception","errorClass":"Vagrant::Errors::NFSDupePerms","httpStatus":null,"severity":"error","filePath":"plugins/hosts/linux/cap/nfs.rb","lineNumber":151,"sourceCode":"        # Takes a hash of folders and removes any duplicate exports that\n        # share the same hostpath to avoid duplicate entries in /etc/exports\n        # ref: GH-4666\n        def self.folder_dupe_check(folders)\n          return_folders = {}\n          # Group by hostpath to see if there are multiple exports coming\n          # from the same folder\n          export_groups = folders.values.group_by { |h| h[:hostpath] }\n\n          # We need to check that each group key only has 1 value,\n          # and if not, check each nfs option. If all nfs options are the same\n          # we're good, otherwise throw an exception\n          export_groups.each do |path,group|\n            if group.size > 1\n              # if the linux nfs options aren't all the same throw an exception\n              group1_opts = group.first[:linux__nfs_options]\n\n              if !group.all? {|g| g[:linux__nfs_options] == group1_opts}\n                raise Vagrant::Errors::NFSDupePerms, hostpath: group.first[:hostpath]\n              else\n                # if they're the same just pick the first one\n                return_folders[path] = group.first\n              end\n            else\n              # just return folder, there are no duplicates\n              return_folders[path] = group.first\n            end\n          end\n          return_folders\n        end\n\n        def self.nfs_cleanup(remove_ids)\n          return if !File.exist?(NFS_EXPORTS_PATH)\n\n          editor = Vagrant::Util::StringBlockEditor.new(nfs_exports_content)\n          remove_ids = Array(remove_ids)\n","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/plugins/hosts/linux/cap/nfs.rb#L133-L169","documentation":"Vagrant::Errors::NFSDupePerms raised at plugins/hosts/linux/cap/nfs.rb:151. While collapsing synced folders that share a hostpath (group_by on :hostpath), the Linux cap checks that every group member has identical linux__nfs_options; /etc/exports cannot carry two permission sets for one directory, so a mismatch raises naming the path. Comparison is plain array equality — element order matters.","triggerScenarios":"A Vagrantfile where two or more `type: \"nfs\"` synced_folders resolve to the same host path but their linux__nfs_options arrays differ in content or order (e.g. one with defaults, one customized; rw vs ro; different uid/gid mappings).","commonSituations":"Copy-pasting a synced_folder block and tweaking options; multi-machine Vagrantfiles sharing a host dir with per-machine options; identical option sets listed in different orders (still unequal via ==).","solutions":["Make linux__nfs_options identical — same elements in the same order — for every synced folder sharing that host path","Or consolidate to a single synced_folder entry for the shared directory","Run `vagrant reload` after fixing the Vagrantfile"],"exampleFix":"# before — same host path, two different option sets\nconfig.vm.synced_folder \"/srv/shared\", \"/a\", type: \"nfs\",\n  linux__nfs_options: [\"rw\",\"no_subtree_check\",\"all_squash\"]\nconfig.vm.synced_folder \"/srv/shared\", \"/b\", type: \"nfs\",\n  linux__nfs_options: [\"ro\",\"no_subtree_check\"]\n# after — one consistent option set for /srv/shared\nconfig.vm.synced_folder \"/srv/shared\", \"/a\", type: \"nfs\",\n  linux__nfs_options: [\"rw\",\"no_subtree_check\",\"all_squash\"]\nconfig.vm.synced_folder \"/srv/shared\", \"/b\", type: \"nfs\",\n  linux__nfs_options: [\"rw\",\"no_subtree_check\",\"all_squash\"]","handlingStrategy":"validation","validationCode":"# Pre-flight: assert one option set per host path before vagrant up\nfolders = { \"/a\" => { hostpath: \"/srv/shared\", linux__nfs_options: [\"rw\",\"no_subtree_check\"] },\n           \"/b\" => { hostpath: \"/srv/shared\", linux__nfs_options: [\"ro\",\"no_subtree_check\"] } }\nfolders.group_by { |_, o| File.expand_path(o[:hostpath]) }.each do |path, list|\n  uniq = list.map { |_, o| o[:linux__nfs_options] }.uniq\n  abort \"#{path} exported with #{uniq.size} different nfs option sets\" if uniq.size > 1\nend","typeGuard":null,"tryCatchPattern":"begin\n  HostLinux::Cap::NFS.nfs_export(env, ui, id, ips, folders)\nrescue Vagrant::Errors::NFSDupePerms => e\n  puts \"conflicting options for #{e.data[:hostpath]} — unify linux__nfs_options\"\n  raise\nend","preventionTips":["Define linux__nfs_options once (a constant) and reuse it for shared paths","Remember array order matters in the equality check","Prefer one synced_folder per shared host directory"],"tags":["nfs","linux","duplicate-config","synced-folders","exports"],"backgroundTag":"conflicting-duplicate-config","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}