diff --git a/meta/lib/oeqa/core/case.py b/meta/lib/oeqa/core/case.py
index ad5524a7142..e71cab5028c 100644
--- a/meta/lib/oeqa/core/case.py
+++ b/meta/lib/oeqa/core/case.py
@@ -44,14 +44,16 @@ class OETestCase(unittest.TestCase):
         clss.tearDownClassMethod()
 
     def _oeSetUp(self):
+        # unittest doesn't call tearDown() if setUp() fails so the decorators
+        # need tearing down here in that case too
         try:
             for d in self.decorators:
                 d.setUpDecorator()
+            self.setUpMethod()
         except:
             for d in self.decorators:
                 d.tearDownDecorator()
             raise
-        self.setUpMethod()
 
     def _oeTearDown(self):
         for d in self.decorators:
diff --git a/meta/lib/oeqa/core/tests/cases/timeout.py b/meta/lib/oeqa/core/tests/cases/timeout.py
index 69cf969a67b..2d7229c18fd 100644
--- a/meta/lib/oeqa/core/tests/cases/timeout.py
+++ b/meta/lib/oeqa/core/tests/cases/timeout.py
@@ -32,3 +32,12 @@ class TimeoutTest(OETestCase):
 
     def testTimeoutUnrelated(self):
         sleep(6)
+
+class TimeoutSetUpFailTest(OETestCase):
+
+    def setUp(self):
+        raise Exception("setUp failed")
+
+    @OETimeout(10)
+    def testTimeoutSetUpFail(self):
+        self.assertTrue(True, msg='How is this possible?')
diff --git a/meta/lib/oeqa/core/tests/test_decorators.py b/meta/lib/oeqa/core/tests/test_decorators.py
index 2c668a9871d..d3305b1e534 100755
--- a/meta/lib/oeqa/core/tests/test_decorators.py
+++ b/meta/lib/oeqa/core/tests/test_decorators.py
@@ -147,6 +147,15 @@ class TestTimeoutDecorator(TestBase):
         msg = "OETestTimeout didn't restore SIGALRM"
         self.assertIs(alarm_signal, signal.getsignal(signal.SIGALRM), msg=msg)
 
+    def test_timeout_setup_fail(self):
+        tests = ['timeout.TimeoutSetUpFailTest.testTimeoutSetUpFail']
+        alarm_signal = signal.getsignal(signal.SIGALRM)
+        tc = self._testLoader(modules=self.modules, tests=tests)
+        self.assertFalse(tc.runTests().wasSuccessful())
+        # signal.alarm() returns the time left on any previous alarm
+        self.assertEqual(signal.alarm(0), 0, msg="OETestTimeout alarm left running after setUp failed")
+        self.assertIs(alarm_signal, signal.getsignal(signal.SIGALRM), msg="OETestTimeout didn't restore SIGALRM")
+
     def test_timeout_cancel(self):
         tests = ['timeout.TimeoutTest.testTimeoutSkip', 'timeout.TimeoutTest.testTimeoutDepends', 'timeout.TimeoutTest.testTimeoutUnrelated']
         msg = 'Unrelated test failed to complete'
