I was caught by this yesterday with an amd64 16.04.1 DVD install to a BIOS+GPT custom ("Something Else") configuration where I had forgotten to create the GPT BIOS Boot Partition for GRUB's core. The Bootloader Error dialog is modal with only a GtkButton "gtk-ok". Reading the ubiquity Python code and XML user interface description files it looks as if the OK button is disabled if *any* changes are made to the device GtkComboBox where the user-selected device is invalid (which is checked by the grub_verify_loop() handler. In my case there was no alternative valid option so once I'd interacted with the GtkComboBox the OK button was disabled and I couldn't close the modal dialog. So the issue seems to be that once the OK button has been disabled it is never re-enabled when selecting other valid options. I spent quite some time trying to understand and track the execution flow but didn't get to the point of testing my bug-fix hypothesis due to lack of time but it is detailed at the end of this comment if anyone cares to test it. /use/lib/ubiquity/ubiquity/frontend/gtk_ui.py::Wizard.run(): (line ~718) # Auto-connecting signals with additional parameters does not work. self.grub_new_device_entry.connect( 'changed', self.grub_verify_loop, self.grub_fail_okbutton) This connects a signal from the device GtkComboBox to the grub_verify_loop() function. /usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py::Wizard.grub_verify_loop() (line ~1706) def grub_verify_loop(self, widget, okbutton): if widget is not None: if validation.check_grub_device(widget.get_child().get_text()): okbutton.set_sensitive(True) else: okbutton.set_sensitive(False) Which will disable the OK button if the device is not valid. /usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py::bootloader_dialog(): (line ~1775) ... response = self.bootloader_fail_dialog.run() self.bootloader_fail_dialog.hide() if response == Gtk.ResponseType.OK: if self.grub_new_device.get_active(): return self.grub_new_device_entry.get_child().get_text() elif self.grub_no_new_device.get_active(): return 'skip' else: return '' else: return '' because bootloader_fail_dialog.run() blocks and never returns the subsequent .hide() and response handling never occurs. In /usr/share/ubiquity/gtk/ubiquity.ui the OK button id is "grub_fail_okbutton" and it is attached to: grub_fail_okbutton The XML also defines a "toggled" signal attached to each of the radio buttons that calls the toggle_grub_fail() handler. /usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py::Wizard.toggle_grub_fail() (line ~1761) def toggle_grub_fail(self, unused_widget): if self.grub_no_new_device.get_active(): self.no_grub_warn.show() self.grub_new_device_entry.set_sensitive(False) self.abort_warn.hide() elif self.grub_fail_option.get_active(): self.abort_warn.show() self.no_grub_warn.hide() self.grub_new_device_entry.set_sensitive(False) else: self.abort_warn.hide() self.no_grub_warn.hide() self.grub_new_device_entry.set_sensitive(True) This changes the visibility of the option-specific warnings that appear when those options are selected and alters the enabled status of the GtkComboBox. So I guess the solution is to add two identical lines here to ensure the OK button is enabled for the 'proceed without GRUB' or 'Cancel installtion' options: def toggle_grub_fail(self, unused_widget): if self.grub_no_new_device.get_active(): self.no_grub_warn.show() self.grub_new_device_entry.set_sensitive(False) self.okbutton.set_sensitive(True) self.abort_warn.hide() elif self.grub_fail_option.get_active(): self.abort_warn.show() self.no_grub_warn.hide() self.grub_new_device_entry.set_sensitive(False) self.okbutton.set_sensitive(True) else: self.abort_warn.hide() self.no_grub_warn.hide() self.grub_new_device_entry.set_sensitive(True)