hashicorp/vagrant · error · VagrantPlugins::SyncedFolderSMB::Errors::PruneShareFailed

Pruning an SMB share failed! Details about the failure are…

Error message

Pruning an SMB share failed! Details about the failure are shown
below. Please inspect the error message and correct any problems.

Share name: %{name}

Stderr: %{stderr}

Stdout: %{stdout}

What it means

SyncedFolderSMB::Errors::PruneShareFailed raised at plugins/hosts/windows/cap/smb.rb:63. When machines go away, Vagrant computes stale `vgt-*` shares, warns about a UAC prompt (sleeping UAC_PROMPT_WAIT), then runs the removal script elevated via `Vagrant::Util::PowerShell.execute(script_path, *prune_shares, sudo: true)`; a non-zero exit raises, with the failing share name extracted from stdout by stripping the literal "share name: " prefix.

Solutions

  1. Remove the named share manually in elevated PowerShell: `Remove-SmbShare -Name "<Share name from error>" -Force` (or `net share <name> /delete`)
  2. Close programs holding files under the share, then retry the vagrant command
  3. Accept the UAC elevation prompt when the prune warning appears — Vagrant waits for it
  4. Bulk-clean stale shares when nothing is running: `Get-SmbShare vgt-* | Remove-SmbShare -Force`

Example fix

# before — share held open, prune fails during `vagrant destroy`
# error: PruneShareFailed name=vgt-abc123-...
# after — free the handle and remove manually, then retry
Get-Process | Where-Object { $_.Path -like 'C:\shared\*' } | Stop-Object -ErrorAction SilentlyContinue
Remove-SmbShare -Name "vgt-abc123-..." -Force
# then: vagrant destroy
Defensive patterns

Strategy: fallback

Validate before calling

# Before destroy, see which stale shares exist and pre-remove them
# powershell: Get-SmbShare -Name "vgt-*" | Select Name,Path
stale = `powershell -NoProfile -Command "Get-SmbShare -Name 'vgt-*' | Select-Object -ExpandProperty Name"`.split
stale.each { |n| system("powershell -Command \"Remove-SmbShare -Name #{n} -Force\"") }

Try / catch

begin
  machine.action_destroy
rescue VagrantPlugins::SyncedFolderSMB::Errors::PruneShareFailed => e
  warn "prune failed for #{e.data[:name]}: #{e.data[:stderr]}"
  # non-fatal for the destroy workflow: log, remove manually, continue
  system("powershell -Command \"Remove-SmbShare -Name '#{e.data[:name]}' -Force\"")
end

Prevention

When it happens

Trigger: `vagrant destroy`/`halt` (or a subsequent up that prunes) on Windows where the elevated Remove-SmbShare fails: UAC prompt dismissed, a share held open by file handles, the share already deleted by someone else, or the Server (lanmanserver) service stopped.

Common situations: User dismisses the UAC dialog during the wait; Explorer or a process holds files in the shared path; stale vgt- shares from crashed runs; group policy restricting share management.

Related errors


AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21). Data as JSON: /api/errors/a3799fb285492350. Report an issue: GitHub.

Appendix: source

Thrown at plugins/hosts/windows/cap/smb.rb:63

              @@logger.info("removing smb share name=#{share_name} id=#{m_id}")
              share_name
            else
              @@logger.info("skipping smb share removal, not owned name=#{share_name}")
              @@logger.debug("smb share ID not present name=#{share_name} id=#{m_id} description=#{share_info["Description"]}")
              nil
            end
          end.compact

          @@logger.debug("shares to be removed: #{prune_shares}")

          if prune_shares.size > 0
            machine.env.ui.warn("\n" + I18n.t("vagrant_sf_smb.uac.prune_warning") + "\n")
            sleep UAC_PROMPT_WAIT
            @@logger.info("remove shares: #{prune_shares}")
            result = Vagrant::Util::PowerShell.execute(script_path, *prune_shares, sudo: true)
            if result.exit_code != 0
              failed_name = result.stdout.to_s.sub("share name: ", "")
              raise SyncedFolderSMB::Errors::PruneShareFailed,
                name: failed_name,
                stderr: result.stderr,
                stdout: result.stdout
            end
          end
        end

        def self.smb_prepare(env, machine, folders, opts)
          script_path = File.expand_path("../../scripts/set_share.ps1", __FILE__)

          shares = []
          current_shares = existing_shares
          folders.each do |id, data|
            hostpath = data[:hostpath].to_s

            chksum_id = Digest::MD5.hexdigest(id)
            name = "vgt-#{machine_id(machine)}-#{chksum_id}"
            data[:smb_id] ||= name

View on GitHub (pinned to 35f3160f4a)