{"record":{"id":"362e10e80254b999","repo":"hashicorp/vagrant","slug":"vagrant-exited-after-cleanup-due-to-external-inter","errorCode":null,"errorMessage":"Vagrant exited after cleanup due to external interrupt.","messagePattern":"Vagrant exited after cleanup due to external interrupt\\.","errorType":"exception","errorClass":"Vagrant::Errors::VagrantInterrupt","httpStatus":null,"severity":"info","filePath":"lib/vagrant/action/warden.rb","lineNumber":35,"sourceCode":"    # interest except to those who are curious about the internal workings\n    # of Vagrant.\n    class Warden\n      attr_accessor :actions, :stack\n\n      def initialize(actions, env)\n        @stack      = []\n        @actions    = actions.map { |m| finalize_action(m, env) }.flatten\n        @logger     = Log4r::Logger.new(\"vagrant::action::warden\")\n        @last_error = nil\n      end\n\n      def call(env)\n        return if @actions.empty?\n\n        begin\n          # Call the next middleware in the sequence, appending to the stack\n          # of \"recoverable\" middlewares in case something goes wrong!\n          raise Errors::VagrantInterrupt if env[:interrupted]\n          action = @actions.shift\n          @logger.info(\"Calling IN action: #{action}\")\n          @stack.unshift(action).first.call(env)\n          raise Errors::VagrantInterrupt if env[:interrupted]\n          @logger.info(\"Calling OUT action: #{action}\")\n        rescue SystemExit, NoMemoryError\n          # This means that an \"exit\" or \"abort\" was called, or we have run out\n          # of memory. In these cases, we just exit immediately.\n          raise\n        rescue Exception => e\n          # We guard this so that the Warden only outputs this once for\n          # an exception that bubbles up.\n          if e != @last_error\n            @logger.error(\"Error occurred: #{e}\")\n            @last_error = e\n          end\n\n          env[\"vagrant.error\"] = e","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/action/warden.rb#L17-L53","documentation":"VagrantInterrupt is raised by Action::Warden#call at lib/vagrant/action/warden.rb:35 before the next middleware is dispatched when env[:interrupted] is truthy. The flag is set by Action::Runner's signal handler after the process receives SIGINT (Ctrl-C). Raising here lets the warden's rescue block run each middleware's recover handler, so cleanup executes before the process exits with this message.","triggerScenarios":"User presses Ctrl-C while a middleware chain (vagrant up, halt, destroy, provision) is between actions; Runner traps SIGINT, sets environment[:interrupted] = true (lib/vagrant/action/runner.rb:96), and the next time warden.rb:35 is reached the interrupt error is raised before @actions.shift runs.","commonSituations":"Long-running 'vagrant up' aborted with Ctrl-C; CI jobs killed by timeout signals; scripts piping SIGINT to a vagrant process; a second interrupt arriving right as an action boundary is crossed.","solutions":["Treat it as expected behavior: the action was aborted and cleaned up; simply re-run the vagrant command when ready","If interrupts are unwanted, avoid sending SIGINT to the process (stop CI timeouts or wrapper scripts that kill the process)","If it appears without any Ctrl-C, check for parent processes or supervisors (systemd, docker stop, watchmedos) sending signals to vagrant"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  env.machine_action(:up, ...) # or CLI invocation\nrescue Vagrant::Errors::VagrantInterrupt\n  # expected on SIGINT: cleanup already ran via warden recover\n  exit 130 # conventional SIGINT exit code\nend","preventionTips":["In automation, give vagrant a generous timeout instead of SIGINT-killing it mid-action","Document that the first Ctrl-C triggers graceful cleanup and this message; a second Ctrl-C aborts immediately"],"tags":["vagrant","interrupt","sigint","middleware","shutdown"],"backgroundTag":"process-interrupt-sigint","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}