{"record":{"id":"d3ab1c73c2cbf7e4","repo":"hashicorp/vagrant","slug":"virtualbox-only-allows-up-to-limit-disks-to-be","errorCode":null,"errorMessage":"VirtualBox only allows up to %{limit} disks to be attached to the\nstorage controller '%{name}'. Please remove some disks from your disk\nconfiguration, or attach a new storage controller.","messagePattern":"VirtualBox only allows up to %(.+?) disks to be attached to the\nstorage controller '%(.+?)'\\. Please remove some disks from your disk\nconfiguration, or attach a new storage controller\\.","errorType":"exception","errorClass":"Vagrant::Errors::VirtualBoxDisksDefinedExceedLimit","httpStatus":null,"severity":"error","filePath":"plugins/providers/virtualbox/cap/configure_disks.rb","lineNumber":37,"sourceCode":"          return {} if defined_disks.empty?\n\n          machine.ui.info(I18n.t(\"vagrant.cap.configure_disks.start\"))\n\n          storage_controllers = machine.provider.driver.read_storage_controllers\n\n          # Check to determine which controller we should attach disks to.\n          # If there is only one storage controller attached to the VM, use\n          # it. If there are multiple controllers (e.g. IDE/SATA), attach DVDs\n          # to the IDE controller and disks to the SATA controller.\n          if storage_controllers.size == 1\n            controller = storage_controllers.first\n\n            # The only way you can define up to the controller limit is if\n            # exactly one disk is a primary disk, otherwise we need to reserve\n            # a slot for the primary\n            if (defined_disks.any? { |d| d.primary } && defined_disks.size > controller.limit) ||\n               defined_disks.size > controller.limit - 1\n              raise Vagrant::Errors::VirtualBoxDisksDefinedExceedLimit,\n                limit: controller.limit,\n                name: controller.name\n            else\n              disk_controller = controller\n              dvd_controller = controller\n            end\n          else\n            disks_defined = defined_disks.select { |d| d.type == :disk }\n            if disks_defined.any?\n              disk_controller = storage_controllers.get_primary_controller\n\n              if (disks_defined.any? { |d| d.primary } && disks_defined.size > disk_controller.limit) ||\n                 disks_defined.size > disk_controller.limit - 1\n                raise Vagrant::Errors::VirtualBoxDisksDefinedExceedLimit,\n                  limit: disk_controller.limit,\n                  name: disk_controller.name\n              end\n            end","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/plugins/providers/virtualbox/cap/configure_disks.rb#L19-L55","documentation":"In the configure_disks capability, when the VM has exactly one storage controller all defined disks and DVDs go to it. Because a non-primary disk needs the controller's port reserved logic, the code raises VirtualBoxDisksDefinedExceedLimit when (a primary disk exists and total defined disks exceed controller.limit) or total disks exceed controller.limit - 1 (one slot stays reserved for the primary disk).","triggerScenarios":"`vagrant up`/disk provisioning with more `config.vm.disk :disk` entries than the single controller's limit minus one — e.g. 30 disks on a SATA controller (limit 30) leaving no slot for the primary, or 29+ entries where none is marked primary.","commonSituations":"Defining dozens of data disks in loops for storage testing on a box that ships only one controller; forgetting that the primary boot disk consumes a slot; scripts scaled up past the controller's port count.","solutions":["Reduce the number of config.vm.disk entries to at most limit-1 when any disk is non-primary (typically <= 29 on SATA)","Mark exactly one disk with `primary: true` and keep the total within controller.limit if you need the full count","Add a second storage controller via `config.vm.customize ['storagectl', :id, '--name', 'SATA2', '--add', 'sata', '--portcount', '30']` and rely on the multi-controller path","Inspect the current controller and limit: `VBoxManage showvminfo <name> --machinereadable | grep -i storagecontroller`"],"exampleFix":"# Vagrantfile - before (single SATA controller, limit 30):\n(1..30).each { |i| config.vm.disk :disk, size: '1GB', name: \"disk-#{i}\" }\n\n# after:\n(1..28).each { |i| config.vm.disk :disk, size: '1GB', name: \"disk-#{i}\" }\n# plus a second controller if more disks are required:\n# config.vm.customize ['storagectl', :id, '--name', 'SATA2', '--add', 'sata', '--portcount', '30']","handlingStrategy":"validation","validationCode":"# before up: single-controller VM - total disks must fit limit (minus 1 when no primary)\nlimit = 30 # SATA port count from `VBoxManage showvminfo <vm> --machinereadable`\ndisks = vagrantfile_disks.select { |d| d[:type] == :disk }\nhas_primary = disks.any? { |d| d[:primary] }\nvalid = has_primary ? disks.size <= limit : disks.size <= limit - 1\nabort 'too many disks for single controller' unless valid","typeGuard":"def disk_count_within_limit?(defined_disks, limit)\n  has_primary = defined_disks.any? { |d| d[:primary] }\n  has_primary ? defined_disks.size <= limit : defined_disks.size <= limit - 1\nend","tryCatchPattern":"begin\n  env.cli('up')\nrescue Vagrant::Errors::VirtualBoxDisksDefinedExceedLimit => e\n  warn \"#{e.extra_data[:name]} holds max #{e.extra_data[:limit]} - shrink config.vm.disk list or add a controller\"\nend","preventionTips":["Keep disk definitions in one array and assert count <= controller limit - 1 in a Vagrantfile guard","Remember the primary/boot disk consumes one slot on a single controller","Add controllers explicitly with storagectl customize blocks before scaling disk counts"],"tags":["virtualbox","disks","storage-controller","limits"],"backgroundTag":"disk-attach-limit-exceeded","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}