diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py
index 92e5ccfaca57b63d78ee6330a49f7abc33becef1..3303892f441a7c5b357ad587cad579a03ad1a83b 100644
--- a/src/_zkapauthorizer/controller.py
+++ b/src/_zkapauthorizer/controller.py
@@ -331,10 +331,11 @@ class PaymentController(object):
         # Ask the redeemer to do the real task of redemption.
         self._log.info("Redeeming random tokens for a voucher ({voucher}).", voucher=voucher)
         d = self.redeemer.redeem(Voucher(voucher), tokens)
-        d.addCallback(
+        d.addCallbacks(
             partial(self._redeemSuccess, voucher),
+            partial(self._redeemFailure, voucher),
         )
-        # XXX This needs an errback!
+        d.addErrback(partial(self._finalRedeemError, voucher))
 
     def _redeemSuccess(self, voucher, unblinded_tokens):
         """
@@ -345,6 +346,14 @@ class PaymentController(object):
         self._log.info("Inserting redeemed unblinded tokens for a voucher ({voucher}).", voucher=voucher)
         self.store.insert_unblinded_tokens_for_voucher(voucher, unblinded_tokens)
 
+    def _redeemFailure(self, voucher, reason):
+        self._log.failure("Redeeming random tokens for a voucher ({voucher}) failed.", reason, voucher=voucher)
+        return None
+
+    def _finalRedeemError(self, voucher, reason):
+        self._log.failure("Redeeming random tokens for a voucher ({voucher}) encountered error.", reason, voucher=voucher)
+        return None
+
 
 def get_redeemer(plugin_name, node_config, announcement, reactor):
     section_name = u"storageclient.plugins.{}".format(plugin_name)