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

The provider for this Vagrant-managed machine is reporting t

Error message

The provider for this Vagrant-managed machine is reporting that it
is not yet ready for SSH. Depending on your provider this can carry
different meanings. Make sure your machine is created and running and
try again. Additionally, check the output of `vagrant status` to verify
that the machine is in the state that you expect. If you continue to
get this error message, please view the documentation for the provider
you're using.

What it means

The ssh_exec middleware (`vagrant ssh`) reads ssh_info from the action env or from `machine.ssh_info`; a nil result is the provider's way of saying the machine cannot do SSH right now (not created, not running, or otherwise unavailable). Vagrant translates that nil into SSHNotReady instead of attempting a connection.

Source

Thrown at lib/vagrant/action/builtin/ssh_exec.rb:33

      #
      # Note: If there are any middleware after `SSHExec`, they will **not**
      # run, since exec replaces the currently running process.
      class SSHExec
        # For quick access to the `SSH` class.
        include Vagrant::Util

        def initialize(app, env)
          @app = app
        end

        def call(env)
          # Grab the SSH info from the machine or the environment
          info = env[:ssh_info]
          info ||= env[:machine].ssh_info

          # If the result is nil, then the machine is telling us that it is
          # not yet ready for SSH, so we raise this exception.
          raise Errors::SSHNotReady if info.nil?

          info[:private_key_path] ||= []

          if info[:private_key_path].empty? && info[:password]
            env[:ui].warn(I18n.t("vagrant.ssh_exec_password"))
          end

          # Exec!
          SSH.exec(info, env[:ssh_opts])
        end
      end
    end
  end
end

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Run `vagrant status` and confirm the machine is 'running'; if not, `vagrant up` first.
  2. If the state looks stuck or inconsistent, `vagrant reload` (or `vagrant destroy && vagrant up`) to get a clean running state.
  3. In scripts, gate ssh on readiness: `vagrant up && vagrant ssh -c 'echo ready'`.

Example fix

# before
vagrant halt
vagrant ssh          # => SSHNotReady

# after
vagrant up
vagrant ssh
Defensive patterns

Strategy: try-catch

Validate before calling

# Shell: only ssh when the machine reports a running state
state=$(vagrant status --machine-readable | awk -F, '$3=="state-id"{print $4}')
[ "$state" = "running" ] && vagrant ssh || echo "machine state: $state (run vagrant up)"

Type guard

# Ruby: narrow on ssh readiness before using ssh_info
def ssh_ready?(machine)
  !machine.ssh_info.nil?
end

raise "not ready" unless ssh_ready?(machine)

Try / catch

# Ruby: rescue and report rather than crashing automation
begin
  machine.action("ssh")
rescue Vagrant::Errors::SSHNotReady => e
  warn "#{machine.name} not ready for SSH (#{machine.state.id}); running vagrant up"
  machine.action("up")
  retry
end

Prevention

When it happens

Trigger: Running `vagrant ssh` when the machine is not created or not running (`vagrant status` shows 'not created'/'poweroff'/'aborted'), during early boot before the provider reports the VM up, or when a provider like Docker has no running container (lib/vagrant/action/builtin/ssh_exec.rb:24-35).

Common situations: SSH-ing after `vagrant halt` or a failed/crashed up; scripts that ssh immediately after launching up in the background; suspended machines whose provider lost track; container stopped underneath Vagrant.

Related errors


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