hashicorp/vagrant · error · Vagrant::Errors::SSHUnavailableWindows

`ssh` executable not found in any directories in the %PATH%

Error message

`ssh` executable not found in any directories in the %PATH% variable. Is an
SSH client installed? Try installing Cygwin, MinGW or Git, all of which
contain an SSH client. Or use your favorite SSH client with the following
authentication information shown below:

Host: %{host}
Port: %{port}
Username: %{username}
Private key: %{key_path}

What it means

In Vagrant::Util::SSH.exec, after both the initial lookup and a fallback Which.which('ssh') fail to find an ssh executable on Windows, Vagrant raises SSHUnavailableWindows — including host, port, username and private key path in the message so you can connect manually with another client. Non-Windows hosts get the plain SSHUnavailable error instead.

Source

Thrown at lib/vagrant/util/ssh.rb:89

        # include ssh, notably git, mingw and cygwin, but make sure ssh is in the path!

        # First try using the original path provided
        if ENV["VAGRANT_PREFER_SYSTEM_BIN"] != "0"
          ssh_path = Which.which("ssh", original_path: true)
        end

        # If we didn't find an ssh executable, see if we shipped one
        if !ssh_path
          ssh_path = Which.which("ssh")
          if ssh_path && Platform.windows? && (Platform.cygwin? || Platform.msys?)
            LOGGER.warn("Failed to locate native SSH executable. Using vendored version.")
            LOGGER.warn("If display issues are encountered, install the ssh package for your environment.")
          end
        end

        if !ssh_path
          if Platform.windows?
            raise Errors::SSHUnavailableWindows,
              host: ssh_info[:host],
              port: ssh_info[:port],
              username: ssh_info[:username],
              key_path: ssh_info[:private_key_path].join(", ")
          end

          raise Errors::SSHUnavailable
        end

        if Platform.windows?
          # On Windows, we need to detect whether SSH is actually "plink"
          # underneath the covers. In this case, we tell the user.
          r = Subprocess.execute(ssh_path)
          if r.stdout.include?("PuTTY Link") || r.stdout.include?("Plink: command-line connection utility")
            raise Errors::SSHIsPuttyLink,
              host: ssh_info[:host],
              port: ssh_info[:port],
              username: ssh_info[:username],

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Install the OpenSSH client: Settings > Apps > Optional Features > OpenSSH Client, or `Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0`
  2. Or install Git for Windows / Cygwin (both ship ssh.exe) and put their bin directory on PATH
  3. Or connect manually using the Host/Port/Username/Private key values the error prints, e.g. with PuTTY

Example fix

# before (Windows)
> vagrant ssh   # SSHUnavailableWindows

# after (admin PowerShell)
> Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
> vagrant ssh
Defensive patterns

Strategy: validation

Validate before calling

require 'vagrant/util/which'
require 'vagrant/util/platform'

if Vagrant::Util::Platform.windows? && !Vagrant::Util::Which.which('ssh')
  abort 'install the Windows OpenSSH Client (or Git for Windows) before vagrant ssh'
end

Try / catch

begin
  Vagrant::Util::SSH.exec(machine.ssh_info)
rescue Vagrant::Errors::SSHUnavailableWindows => e
  puts e.message # contains Host/Port/Username/Private key for manual connect
end

Prevention

When it happens

Trigger: `vagrant ssh` on a Windows host where no OpenSSH client is on PATH: the optional OpenSSH Client feature is disabled, Git for Windows/Cygwin are not installed, or the invoking context (service, CI) has a sanitized PATH.

Common situations: Fresh Windows installs; hardened CI agents; PATH clobbered by other installers.

Understand the failure class

Related errors


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