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

The private key to connect to the machine via SSH must be ow

Error message

The private key to connect to the machine via SSH must be owned
by the user running Vagrant. This is a strict requirement from
SSH itself. Please fix the following key to be owned by the user
running Vagrant:

%{key_path}

What it means

Vagrant::Util::SSH.check_key_permissions stats the private key and raises SSHKeyBadOwner when the file is not owned by the current user and the process is not root — mirroring OpenSSH's strict ownership rule for identity files. Windows hosts and WSL windows-access bypass paths return before the check.

Source

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

      LOGGER = Log4r::Logger.new("vagrant::util::ssh")

      # Checks that the permissions for a private key are valid, and fixes
      # them if possible. SSH requires that permissions on the private key
      # are 0600 on POSIX based systems. This will make a best effort to
      # fix these permissions if they are not properly set.
      #
      # @param [Pathname] key_path The path to the private key.
      def self.check_key_permissions(key_path)
        # Don't do anything if we're on Windows, since Windows doesn't worry
        # about key permissions.
        return if Platform.windows? || Platform.wsl_windows_access_bypass?(key_path)

        LOGGER.debug("Checking key permissions: #{key_path}")
        stat = key_path.stat

        if !stat.owned? && Process.uid != 0
          # The SSH key must be owned by ourselves, unless we're root
          raise Errors::SSHKeyBadOwner, key_path: key_path
        end

        if FileMode.from_octal(stat.mode) != "600"
          LOGGER.info("Attempting to correct key permissions to 0600")
          key_path.chmod(0600)

          # Re-stat the file to get the new mode, and verify it worked
          stat = key_path.stat
          if FileMode.from_octal(stat.mode) != "600"
            raise Errors::SSHKeyBadPermissions, key_path: key_path
          end
        end
      rescue Errno::EPERM
        # This shouldn't happen since we verify we own the file, but
        # it is possible in theory, so we raise an error.
        raise Errors::SSHKeyBadPermissions, key_path: key_path
      end

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. chown the listed key back to the running user: `sudo chown $USER <key_path>` and `chmod 600 <key_path>`
  2. Or delete the key file so Vagrant regenerates a fresh keypair on the next up/ssh
  3. Run vagrant consistently as the user who owns the project and .vagrant tree

Example fix

# before
$ vagrant ssh   # SSHKeyBadOwner: .vagrant/machines/default/virtualbox/private_key

# after
$ sudo chown $USER .vagrant/machines/default/virtualbox/private_key
$ chmod 600 .vagrant/machines/default/virtualbox/private_key
$ vagrant ssh
Defensive patterns

Strategy: validation

Validate before calling

st = File.stat(key_path)
unless st.owned? || Process.uid == 0
  abort "#{key_path} is owned by uid #{st.uid}; run: sudo chown #{Process.uid} #{key_path}"
end

Try / catch

begin
  Vagrant::Util::SSH.check_key_permissions(Pathname.new(key))
rescue Vagrant::Errors::SSHKeyBadOwner
  require 'etc'
  system('sudo', 'chown', Etc.getlogin, key) or raise
  retry
end

Prevention

When it happens

Trigger: The private key (e.g. .vagrant/machines/<name>/virtualbox/private_key) is owned by another user — files created under sudo, projects restored from a backup as root, or a workspace shared between users — while vagrant runs as the non-owner, non-root user.

Common situations: Running vagrant under sudo once (keys become root-owned); cloning/restoring projects under a different uid; multi-user hosts sharing one directory.

Related errors


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