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

The Vagrant virtual environment you are trying to package mu

Error message

The Vagrant virtual environment you are trying to package must be powered off.

What it means

The VirtualBox Export action refuses to package a machine that is not fully powered off: it checks @env[:machine].state.id != :poweroff and raises VMPowerOffToPackage before invoking driver.export. An .ova export requires the VM stopped because VirtualBox can only snapshot/clone a powered-off disk chain cleanly.

Source

Thrown at plugins/providers/virtualbox/action/export.rb:18

# Copyright IBM Corp. 2010, 2025
# SPDX-License-Identifier: BUSL-1.1

require "fileutils"
require 'vagrant/util/platform'

module VagrantPlugins
  module ProviderVirtualBox
    module Action
      class Export
        def initialize(app, env)
          @app = app
        end

        def call(env)
          @env = env

          raise Vagrant::Errors::VMPowerOffToPackage if \
            @env[:machine].state.id != :poweroff

          export

          @app.call(env)
        end

        def export
          @env[:ui].info I18n.t("vagrant.actions.vm.export.exporting")
          @env[:machine].provider.driver.export(ovf_path) do |progress|
            @env[:ui].rewriting do |ui|
              ui.clear_line
              ui.report_progress(progress.percent, 100, false)
            end
          end

          # Clear the line a final time so the next data can appear
          # alone on the line.

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Halt the machine first: `vagrant halt` (wait for state 'poweroff'), then `vagrant package`
  2. If halt hangs, force it: `vagrant halt --force`, or power off from VirtualBox GUI/`VBoxManage controlvm <name> poweroff`
  3. In automation scripts, insert `vagrant halt` (and optionally `vagrant halt --force` fallback) before the package step
  4. Check `vagrant status` shows 'poweroff' before packaging

Example fix

# before:
vagrant up
vagrant package --output mybox.box   # -> VMPowerOffToPackage

# after:
vagrant up
vagrant ssh -c 'sudo poweroff' || vagrant halt
vagrant status                        # must show: poweroff
vagrant package --output mybox.box
Defensive patterns

Strategy: validation

Validate before calling

# guard the package step in automation
state = `vagrant status --machine-readable`.lines.find { |l| l.include?('state-') }
abort 'VM not powered off - run vagrant halt first' unless state&.include?('poweroff')

Type guard

def packageable?(machine)
  machine.state.id == :poweroff   # only :poweroff passes the Export action check
end

Try / catch

begin
  env.cli('package', '--output', out)
rescue Vagrant::Errors::VMPowerOffToPackage
  env.cli('halt')
  retry
end

Prevention

When it happens

Trigger: `vagrant package` (or any flow reaching the Export action) while the machine state is running, saved, abend, or paused — anything other than :poweroff.

Common situations: Running `vagrant package` right after `vagrant up` without halting; assuming `vagrant suspend` is sufficient (saved state still fails); provisioning automation that packages as a final step without a halt step.

Related errors


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