{"record":{"id":"cedad66f60b0ab20","repo":"hashicorp/vagrant","slug":"the-upload-was-interrupted-by-an-external-signal","errorCode":null,"errorMessage":"The upload was interrupted by an external signal. It did not\ncomplete.","messagePattern":"The upload was interrupted by an external signal\\. It did not\ncomplete\\.","errorType":"exception","errorClass":"Vagrant::Errors::UploaderInterrupted","httpStatus":null,"severity":"error","filePath":"lib/vagrant/util/uploader.rb","lineNumber":81,"sourceCode":"\n      def execute_curl(options, subprocess_options, &data_proc)\n        options = options.dup\n        options << subprocess_options\n\n        # Create the callback that is called if we are interrupted\n        interrupted  = false\n        int_callback = Proc.new do\n          @logger.info(\"Uploader interrupted!\")\n          interrupted = true\n        end\n\n        # Execute!\n        result = Busy.busy(int_callback) do\n          Subprocess.execute(\"curl\", *options, &data_proc)\n        end\n\n        # If the upload was interrupted, then raise a specific error\n        raise Errors::UploaderInterrupted if interrupted\n\n        # If it didn't exit successfully, we need to parse the data and\n        # show an error message.\n        if result.exit_code != 0\n          @logger.warn(\"Uploader exit code: #{result.exit_code}\")\n          check = result.stderr.match(/\\n*curl:\\s+\\((?<code>\\d+)\\)\\s*(?<error>.*)$/)\n          if !check\n            err_msg = result.stderr\n          else\n            err_msg = check[:error]\n          end\n\n          raise Errors::UploaderError,\n            exit_code: result.exit_code,\n            message: err_msg\n        end\n\n        if @ui","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/util/uploader.rb#L63-L99","documentation":"The upload counterpart of DownloaderInterrupted: Vagrant::Util::Uploader wraps its curl upload in Busy.busy with an INT callback; when an external signal interrupts the transfer (interrupted = true) it raises UploaderInterrupted rather than a curl-exit error. This class backs box publication uploads such as `vagrant cloud publish`.","triggerScenarios":"Ctrl-C (or any SIGINT) while `vagrant cloud publish` / a box upload is streaming the .box file; CI cancellations or signal-forwarding supervisors killing the curl child mid-upload.","commonSituations":"Cancelling slow multi-GB box uploads; CI timeouts aborting publish jobs; wrappers forwarding signals unexpectedly.","solutions":["Re-run the publish once conditions are stable; first check the Vagrant Cloud UI for a partial/failed version and remove it","If the SIGINT was unintended, fix the source (timeout wrappers, init signal policies) or exclude vagrant from forwarding","For very large boxes, shorten the exposure window: upload on a stable link, or prepare/split the artifact beforehand"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"tries = 0\nbegin\n  uploader.upload!\nrescue Vagrant::Errors::UploaderInterrupted\n  tries += 1\n  sleep 5\n  cleanup_partial_cloud_version!\n  retry if tries < 3\nend","preventionTips":["Do not interrupt cloud publish mid-upload; cancel before it starts","Remove partial Vagrant Cloud versions before republishing","Run large box uploads on stable links to avoid manual cancels"],"tags":["upload","interrupt","sigint","curl","vagrant-cloud"],"backgroundTag":"upload-interrupted","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}