diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py
index a87de63d5e..bffb1adf62 100644
--- a/ironic/common/pxe_utils.py
+++ b/ironic/common/pxe_utils.py
@@ -369,7 +369,8 @@ def create_ipxe_boot_script():
     """Render the iPXE boot script into the HTTP root directory"""
     boot_script = utils.render_template(
         CONF.pxe.ipxe_boot_script,
-        {'ipxe_for_mac_uri': PXE_CFG_DIR_NAME + '/'})
+        {'ipxe_for_mac_uri': PXE_CFG_DIR_NAME + '/',
+         'ipxe_fallback_script': CONF.pxe.ipxe_fallback_script})
     bootfile_path = os.path.join(
         CONF.deploy.http_root,
         os.path.basename(CONF.pxe.ipxe_boot_script))
diff --git a/ironic/conf/pxe.py b/ironic/conf/pxe.py
index 81aef8e74d..08c554f870 100644
--- a/ironic/conf/pxe.py
+++ b/ironic/conf/pxe.py
@@ -144,6 +144,10 @@ opts = [
                    '$pybasedir', 'drivers/modules/boot.ipxe'),
                help=_('On ironic-conductor node, the path to the main iPXE '
                       'script file.')),
+    cfg.StrOpt('ipxe_fallback_script',
+               help=_('File name (e.g. inspector.ipxe) of an iPXE script to '
+                      'fall back to when booting to a MAC-specific script '
+                      'fails. When not set, booting will fail in this case.')),
     cfg.IntOpt('ipxe_timeout',
                default=0,
                help=_('Timeout value (in seconds) for downloading an image '
diff --git a/ironic/drivers/modules/boot.ipxe b/ironic/drivers/modules/boot.ipxe
index 4739695bab..4ed58497ca 100644
--- a/ironic/drivers/modules/boot.ipxe
+++ b/ironic/drivers/modules/boot.ipxe
@@ -11,12 +11,22 @@ echo Attempting to boot from MAC ${net${netid}/mac:hexhyp}
 chain {{ ipxe_for_mac_uri }}${net${netid}/mac:hexhyp} || goto loop
 
 :loop_done
+{% if ipxe_fallback_script -%}
+chain {{ ipxe_fallback_script }} | goto boot_failed
+
+:boot_failed
+{% endif -%}
 echo PXE boot failed! No configuration found for any of the present NICs.
 echo Press any key to reboot...
 prompt --timeout 180
 reboot
 
 :old_rom
+{% if ipxe_fallback_script -%}
+chain {{ ipxe_fallback_script }} | goto boot_failed_old_rom
+
+:boot_failed_old_rom
+{% endif -%}
 echo PXE boot failed! No configuration found for NIC ${mac:hexhyp}.
 echo Please update your iPXE ROM and retry.
 echo Press any key to reboot...
diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py
index ea0ef4c092..0534a5b6b1 100644
--- a/ironic/tests/unit/common/test_pxe_utils.py
+++ b/ironic/tests/unit/common/test_pxe_utils.py
@@ -154,6 +154,17 @@ class TestPXEUtils(db_base.DbTestCase):
 
         self.assertEqual(str(expected_template), rendered_template)
 
+    def test_fallback_ipxe_boot_script(self):
+        rendered_template = utils.render_template(
+            CONF.pxe.ipxe_boot_script,
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': 'inspector.ipxe'})
+
+        with open('ironic/tests/unit/drivers/boot-fallback.ipxe') as f:
+            expected_template = f.read().rstrip()
+
+        self.assertEqual(str(expected_template), rendered_template)
+
     def test_default_ipxe_config(self):
         # NOTE(lucasagomes): iPXE is just an extension of the PXE driver,
         # it doesn't have it's own configuration option for template.
@@ -714,7 +725,8 @@ class TestPXEUtils(db_base.DbTestCase):
             'foo')
         render_mock.assert_called_once_with(
             CONF.pxe.ipxe_boot_script,
-            {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': None})
 
     @mock.patch.object(os.path, 'isfile', lambda path: True)
     @mock.patch('ironic.common.utils.file_has_content', autospec=True)
@@ -735,7 +747,27 @@ class TestPXEUtils(db_base.DbTestCase):
             'foo')
         render_mock.assert_called_once_with(
             CONF.pxe.ipxe_boot_script,
-            {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': None})
+
+    @mock.patch.object(os.path, 'isfile', lambda path: False)
+    @mock.patch('ironic.common.utils.file_has_content', autospec=True)
+    @mock.patch('ironic.common.utils.write_to_file', autospec=True)
+    @mock.patch('ironic.common.utils.render_template', autospec=True)
+    def test_create_ipxe_boot_script_fallback(self, render_mock, write_mock,
+                                              file_has_content_mock):
+        self.config(ipxe_fallback_script='inspector.ipxe', group='pxe')
+        render_mock.return_value = 'foo'
+        pxe_utils.create_ipxe_boot_script()
+        self.assertFalse(file_has_content_mock.called)
+        write_mock.assert_called_once_with(
+            os.path.join(CONF.deploy.http_root,
+                         os.path.basename(CONF.pxe.ipxe_boot_script)),
+            'foo')
+        render_mock.assert_called_once_with(
+            CONF.pxe.ipxe_boot_script,
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': 'inspector.ipxe'})
 
     @mock.patch.object(os.path, 'isfile', lambda path: True)
     @mock.patch('ironic.common.utils.file_has_content', autospec=True)
diff --git a/ironic/tests/unit/drivers/boot-fallback.ipxe b/ironic/tests/unit/drivers/boot-fallback.ipxe
new file mode 100644
index 0000000000..bf8ab414cd
--- /dev/null
+++ b/ironic/tests/unit/drivers/boot-fallback.ipxe
@@ -0,0 +1,31 @@
+#!ipxe
+
+# NOTE(lucasagomes): Loop over all network devices and boot from
+# the first one capable of booting. For more information see:
+# https://bugs.launchpad.net/ironic/+bug/1504482
+set netid:int32 -1
+:loop
+inc netid || chain pxelinux.cfg/${mac:hexhyp} || goto old_rom
+isset ${net${netid}/mac} || goto loop_done
+echo Attempting to boot from MAC ${net${netid}/mac:hexhyp}
+chain pxelinux.cfg/${net${netid}/mac:hexhyp} || goto loop
+
+:loop_done
+chain inspector.ipxe | goto boot_failed
+
+:boot_failed
+echo PXE boot failed! No configuration found for any of the present NICs.
+echo Press any key to reboot...
+prompt --timeout 180
+reboot
+
+:old_rom
+chain inspector.ipxe | goto boot_failed_old_rom
+
+:boot_failed_old_rom
+echo PXE boot failed! No configuration found for NIC ${mac:hexhyp}.
+echo Please update your iPXE ROM and retry.
+echo Press any key to reboot...
+prompt --timeout 180
+reboot
+
diff --git a/ironic/tests/unit/drivers/modules/test_ipxe.py b/ironic/tests/unit/drivers/modules/test_ipxe.py
index 45a68eeb37..2254a2c727 100644
--- a/ironic/tests/unit/drivers/modules/test_ipxe.py
+++ b/ironic/tests/unit/drivers/modules/test_ipxe.py
@@ -395,7 +395,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
             'foo')
         render_mock.assert_called_once_with(
             CONF.pxe.ipxe_boot_script,
-            {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': None})
 
     @mock.patch.object(os.path, 'isfile', lambda path: False)
     @mock.patch('ironic.common.utils.file_has_content', autospec=True)
@@ -415,7 +416,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
             'foo')
         render_mock.assert_called_once_with(
             CONF.pxe.ipxe_boot_script,
-            {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+            {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+             'ipxe_fallback_script': None})
 
     @mock.patch.object(os.path, 'isfile', lambda path: True)
     @mock.patch.object(common_utils, 'file_has_content', lambda *args: True)
diff --git a/releasenotes/notes/ipxe-fallback-a10c8ce422caa429.yaml b/releasenotes/notes/ipxe-fallback-a10c8ce422caa429.yaml
new file mode 100644
index 0000000000..0f0d602368
--- /dev/null
+++ b/releasenotes/notes/ipxe-fallback-a10c8ce422caa429.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Adds a new configuration option ``[pxe]ipxe_fallback_script`` which allows
+    iPXE boot to fall back to e.g. ironic-inspector iPXE script.