diff --git a/apertis_tests_lib/tumbler.py b/apertis_tests_lib/tumbler.py
index 74862efe2bbd43107a5b2c0af4d48486681a0ab4..17661ce956f7cd4ac39f693d378fcd8c7fe83f35 100644
--- a/apertis_tests_lib/tumbler.py
+++ b/apertis_tests_lib/tumbler.py
@@ -30,6 +30,20 @@ class TumblerMixin:
             None)
         self.tumbler.connect('g-signal', self.__g_signal_cb)
 
+        # Track pending errors. Tumbler emits three signals which we care
+        # about:
+        #  - Ready, which indicates successful thumbnailing for some URIs
+        #  - Error, which indicates errors in thumbnailing for some URIs
+        #  - Finished, which is the final signal emitted for a request
+        # Ready and Error may both be emitted for the same URI, for example if
+        # one of the thumbnailers encounters an error when thumbnailing that
+        # URI, but another thumbnailer subsequently succeeds.
+        # Therefore we must track errors and only propagate them when Finished
+        # is received.
+        #
+        # Each element of this list of a tuple: (uri, error_message).
+        self.tumbler_errors = []
+
         # Spy on unicast signals that weren't meant for us, because
         # the Thumbnailer API uses those, and we want to use them to
         # determine when it has finished. GDBus doesn't have
@@ -54,13 +68,30 @@ class TumblerMixin:
         elif signal_name == 'Finished':
             child = parameters.get_child_value(0)
             self.tumbler_queue.remove(child.get_uint32())
+
+            # Any errors remaining?
+            if len(self.tumbler_errors) > 0:
+                l = [': '.join(p) for p in self.tumbler_errors]
+                raise Exception("Error creating thumbnails: %s" % ', '.join(l))
+
+            # Clear them.
+            self.tumbler_errors = []
+        elif signal_name == 'Ready':
+            child = parameters.get_child_value(1)
+            uris = child.get_strv()
+
+            # Remove any now-successful URIs from the error list.
+            self.tumbler_errors = [p for p in self.tumbler_errors
+                                   if p[0] not in uris]
         elif signal_name == 'Error':
             child = parameters.get_child_value(1)
             uris = child.get_strv()
             child = parameters.get_child_value(3)
             msg = child.get_string()
-            raise Exception("Error creating thumbnail for %s: %s" %
-                            ', '.join(uris), msg)
+
+            # Append to the error list.
+            for uri in uris:
+                self.tumbler_errors.append((uri, msg))
 
     def __get_supported_cb(self, source, result):
         self.tumbler.call_finish(result)