diff --git a/lib/daemon.py b/lib/daemon.py
index 0fba74db94a73dc838c6e9c50fcd432e7510f45f..ff7708972ea4d677d101c5e42e3324ae9aa044bf 100644
--- a/lib/daemon.py
+++ b/lib/daemon.py
@@ -166,7 +166,8 @@ class AsyncUDPSocket(asyncore.dispatcher):
     @return: True if some data has been handled, False otherwise
 
     """
-    if utils.WaitForFdCondition(self, select.POLLIN, timeout) & select.POLLIN:
+    result = utils.WaitForFdCondition(self, select.POLLIN, timeout)
+    if result is not None and result & select.POLLIN:
       self.do_read()
       return True
     else:
diff --git a/lib/utils.py b/lib/utils.py
index c52e91ed29e00629c5f98dda298ec6280a34f1ea..c32ad206b0c42ca43674470e4824f22832403da6 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1579,8 +1579,11 @@ def WaitForFdCondition(fdobj, event, timeout):
   """
   if timeout is not None:
     retrywaiter = FdConditionWaiterHelper(timeout)
-    result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
-                   args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
+    try:
+      result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
+                     args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
+    except RetryTimeout:
+      result = None
   else:
     result = None
     while result is None:
@@ -2606,6 +2609,9 @@ def Retry(fn, delay, timeout, args=None, wait_fn=time.sleep,
       return fn(*args)
     except RetryAgain:
       pass
+    except RetryTimeout:
+      raise errors.ProgrammerError("Nested retry loop detected that didn't"
+                                   " handle RetryTimeout")
 
     remaining_time = end_time - _time_fn()
 
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index 17d10fea653bf2f643442a4c051df026ef6b0b4a..e8f14c3bfb6d4004ac19570200babbabfe66f968 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -1535,5 +1535,28 @@ class TestMakedirs(unittest.TestCase):
     self.assert_(os.path.isdir(path))
 
 
+class TestRetry(testutils.GanetiTestCase):
+  @staticmethod
+  def _RaiseRetryAgain():
+    raise utils.RetryAgain()
+
+  def _WrongNestedLoop(self):
+    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
+
+  def testRaiseTimeout(self):
+    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
+                          self._RaiseRetryAgain, 0.01, 0.02)
+
+  def testComplete(self):
+    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
+
+  def testNestedLoop(self):
+    try:
+      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
+                            self._WrongNestedLoop, 0, 1)
+    except utils.RetryTimeout:
+      self.fail("Didn't detect inner loop's exception")
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()