diff --git a/common/archiveNS/Tape.cpp b/common/archiveNS/Tape.cpp
index d689d34908a01ceb86d3609fb6703def2e6d8563..aa0817881914bf38493169d2d54dc1bb0d945740 100644
--- a/common/archiveNS/Tape.cpp
+++ b/common/archiveNS/Tape.cpp
@@ -68,3 +68,11 @@ bool cta::Tape::Status::availableToWrite() {
   return !busy && !archived && !disabled && !readonly && !full;
 }
 
+//------------------------------------------------------------------------------
+// Status::availableToRead()
+//------------------------------------------------------------------------------
+bool cta::Tape::Status::availableToRead() {
+  return !busy && !archived && !disabled;
+}
+
+
diff --git a/common/archiveNS/Tape.hpp b/common/archiveNS/Tape.hpp
index dac1c484538e4dea92737dd9e463993698efc55d..57459928cde61cc2113c8830924128fbc3fbb83d 100644
--- a/common/archiveNS/Tape.hpp
+++ b/common/archiveNS/Tape.hpp
@@ -116,6 +116,7 @@ struct Tape {
     bool readonly;
     bool full;
     bool availableToWrite();
+    bool availableToRead();
   };
   
   /**
diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp
index aeb0fdf120feb4e3b9c6dd14481fd9778d4abe88..e222ca5fb5261d92f92c30cab3574142daab460a 100644
--- a/scheduler/OStoreDB/OStoreDB.cpp
+++ b/scheduler/OStoreDB/OStoreDB.cpp
@@ -1220,7 +1220,27 @@ OStoreDB::TapeMountDecisionInfo::TapeMountDecisionInfo(
 
 std::unique_ptr<SchedulerDatabase::RetrieveMount> 
   OStoreDB::TapeMountDecisionInfo::createRetrieveMount(
-    const std::string& vid, const std::string driveName) {
+    const std::string& vid, const std::string driveName, 
+    const std::string& logicalLibrary, const std::string& hostName, time_t startTime) {
+  // In order to create the mount, we have to:
+  // Check we actually hold the scheduling lock
+  // Check the tape exists, add it to ownership and set its activity status to 
+  // busy, with the current agent pointing to it for unbusying
+  // Set the drive status to up, but do not commit anything to the drive register
+  // the drive register does not need garbage collection as it should reflect the
+  // latest known state of the drive (and its absence of updating if needed)
+  // Prepare the return value
+  std::unique_ptr<OStoreDB::RetrieveMount> privateRet(
+    new OStoreDB::RetrieveMount(m_objectStore, m_agent));
+  auto &rm = *privateRet;
+  // Check we hold the scheduling lock
+  if (!m_lockTaken)
+    throw SchedulingLockNotHeld("In OStoreDB::TapeMountDecisionInfo::createRetrieveMount: "
+      "cannot create mount without holding scheduling lock");
+  // Find the tape and update it
+  rm.mountInfo.vid = vid;
+  rm.mountInfo.drive = driveName;
+  rm.mountInfo.logicalLibrary = "";
   throw NotImplemented("Not Implemented");
 }
  
@@ -1339,11 +1359,25 @@ void OStoreDB::ArchiveMount::complete(time_t completionTime) {
   t.commit();
 }
 
-
 OStoreDB::ArchiveJob::ArchiveJob(const std::string& jobAddress, 
   objectstore::Backend& os, objectstore::Agent& ag): m_jobOwned(false),
   m_objectStore(os), m_agent(ag), m_atfr(jobAddress, os) {}
 
+OStoreDB::RetrieveMount::RetrieveMount(objectstore::Backend& os, objectstore::Agent& a):
+  m_objectStore(os), m_agent(a) { }
+
+const OStoreDB::RetrieveMount::MountInfo& OStoreDB::RetrieveMount::getMountInfo() {
+  return mountInfo;
+}
+
+auto  OStoreDB::RetrieveMount::getNextJob() -> std::unique_ptr<RetrieveJob> {
+  throw NotImplemented("In OStoreDB::RetrieveMount::getNextJob: not implemented");
+}
+
+void OStoreDB::RetrieveMount::complete(time_t completionTime) {
+  throw NotImplemented("In OStoreDB::RetrieveMount::getNextJob: not implemented");
+}
+
 
 void OStoreDB::ArchiveJob::fail() {
   if (!m_jobOwned)
diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp
index 7d932f76a0adf2453bacd25cff2f9b23ffde5625..b915b079c980ec91c53509f71e78e8fd5d60f282 100644
--- a/scheduler/OStoreDB/OStoreDB.hpp
+++ b/scheduler/OStoreDB/OStoreDB.hpp
@@ -54,8 +54,10 @@ public:
       const std::string & vid, const std::string & tapePool,
       const std::string driveName, const std::string& logicalLibrary, 
       const std::string & hostName, time_t startTime);
-    virtual std::unique_ptr<SchedulerDatabase::RetrieveMount> createRetrieveMount(const std::string & vid,
-      const std::string driveName);
+    virtual std::unique_ptr<SchedulerDatabase::RetrieveMount> createRetrieveMount(
+      const std::string & vid, const std::string driveName,
+      const std::string& logicalLibrary, const std::string& hostName, 
+      time_t startTime);
     virtual ~TapeMountDecisionInfo();
   private:
     TapeMountDecisionInfo (objectstore::Backend &, objectstore::Agent &);
@@ -102,6 +104,19 @@ public:
     objectstore::Agent & m_agent;
     objectstore::ArchiveToFileRequest m_atfr;
   };
+  
+  /* === Retrieve Mount handling ============================================ */
+  class RetrieveMount: public SchedulerDatabase::RetrieveMount {
+    friend class TapeMountDecisionInfo;
+  private:
+    RetrieveMount(objectstore::Backend &, objectstore::Agent &);
+    objectstore::Backend & m_objectStore;
+    objectstore::Agent & m_agent;
+  public:
+    virtual const MountInfo & getMountInfo();
+    virtual std::unique_ptr<RetrieveJob> getNextJob();
+    virtual void complete(time_t completionTime);
+  };
 
   /* === Admin host handling ================================================ */
   virtual void createAdminHost(const std::string& hostName, 
diff --git a/scheduler/RetrieveJob.cpp b/scheduler/RetrieveJob.cpp
index d3f67dd96e5d047a992dc393072374278505dd9a..ae3d5ba2eff4101e20eb6d7d5df3e40b77ee7ef0 100644
--- a/scheduler/RetrieveJob.cpp
+++ b/scheduler/RetrieveJob.cpp
@@ -36,19 +36,19 @@ cta::RetrieveJob::RetrieveJob(/*RetrieveMount &mount,*/
   archiveFile(archiveFile),
   remotePathAndStatus(remotePathAndStatus),
   tapeFileLocation(tapeFileLocation),
-  positioningMethod(positioningMethod) {}
+  positioningMethod(positioningMethod),
+  transferredSize(std::numeric_limits<decltype(transferredSize)>::max()) {}
 
 //------------------------------------------------------------------------------
 // complete
 //------------------------------------------------------------------------------
-void cta::RetrieveJob::complete(const uint32_t checksumOfTransfer, 
-  const uint64_t fileSizeOfTransfer) {
+void cta::RetrieveJob::complete() {
 }
   
 //------------------------------------------------------------------------------
 // failed
 //------------------------------------------------------------------------------
-void cta::RetrieveJob::failed(const exception::Exception &ex) {
+void cta::RetrieveJob::failed() {
 }
   
 //------------------------------------------------------------------------------
diff --git a/scheduler/RetrieveJob.hpp b/scheduler/RetrieveJob.hpp
index bf38d8d10bebbeffb58b70af703b5775ecec587e..b17ef38878deee593b57ed262f79e1806c801c00 100644
--- a/scheduler/RetrieveJob.hpp
+++ b/scheduler/RetrieveJob.hpp
@@ -25,6 +25,7 @@
 #include "scheduler/PositioningMethod.hpp"
 
 #include <string>
+#include <limits>
 
 namespace cta {
 
@@ -46,7 +47,7 @@ protected:
   /**
    * Empty constructor. TODO: to be removed in the future when we put in the reference to the owning mount;
    */
-  RetrieveJob() {}
+  RetrieveJob(): transferredSize(std::numeric_limits<decltype(transferredSize)>::max()) {}
 
   /**
    * Constructor. It is not public as it is generated by the RetrieveMount.
@@ -71,22 +72,18 @@ public:
   virtual ~RetrieveJob() throw() = 0;
 
   /**
-   * Indicates that the job was successful
-   *
-   * @param checksumOfTransfer The adler-32 checksum of the file as calculated
-   * during the execution of the job.
-   * @param fileSizeOfTransfer The size of the file as calculated during the
-   * execution of the job.
+   * Indicates that the job was successful. The checksum and the size of the 
+   * transfer should already stored in the object beforehand. Result setting
+   * and calling complete are done in 2 different threads (disk write and 
+   * reporter thread, respectively).
    */
-  virtual void complete(const uint32_t checksumOfTransfer,
-    const uint64_t fileSizeOfTransfer);
+  virtual void complete();
   
   /**
-   * Indicates that the job failed
-   *
-   * @param ex The reason for the failure.
+   * Indicates that the job failed. Like for complete(), reason for failure
+   * should already be recorded in the object beforehand.
    */
-  virtual void failed(const exception::Exception &ex);
+  virtual void failed();
   
   /**
    * Indicates that the job should be tried again (typically reaching the end 
@@ -119,6 +116,23 @@ public:
    */
   PositioningMethod positioningMethod;
   
+  /**
+   * The checksum of the transferred data. This should be set before calling 
+   * complete()
+   */
+  Checksum transferredChecksum;
+  
+  /**
+   * The size of the transferred data. This should be set before calling 
+   * complete().
+   */
+  uint64_t transferredSize;
+  
+  /**
+   * The error string. This should be set before calling failed().
+   */
+  std::string failureMessage;
+  
 }; // class RetrieveJob
 
 } // namespace cta
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 1880b0668fb7730cf3cf6c44dcd3ecd6a11dfda1..fb4bdd9cf5ec998b81e2b3c43f64d4db7e866d14 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -888,7 +888,25 @@ std::unique_ptr<cta::TapeMount> cta::Scheduler::getNextMount(
         }
       }
     } else if (m->type==cta::MountType::RETRIEVE) {
-      throw NotImplemented("");
+      // We know the tape we intend to mount. We have to validate the tape is 
+      // actually available to read, and pass on it if no.
+      auto tapesList = m_db.getTapes();
+      for (auto t=tapesList.begin(); t!=tapesList.end(); t++) {
+        if (t->vid == m->vid && t->status.availableToRead()) {
+          try {
+            std::unique_ptr<RetrieveMount> internalRet (new RetrieveMount());
+            // Get the db side of the session
+            internalRet->m_dbMount.reset(mountInfo->createRetrieveMount(t->vid, 
+                driveName,
+                logicalLibraryName, 
+                Utils::getShortHostname(), 
+                time(NULL)).release());
+            return std::unique_ptr<TapeMount> (internalRet.release()); 
+         } catch (cta::exception::Exception & ex) {
+           continue;
+         }
+        }
+      }
     } else {
       throw std::runtime_error("In Scheduler::getNextMount unexpected mount type");
     }
diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp
index efae9930a24c34712552f8597ea999ffe5433d70..96b88553148777619946735f6e03e71c8b40fdf5 100644
--- a/scheduler/SchedulerDatabase.hpp
+++ b/scheduler/SchedulerDatabase.hpp
@@ -235,8 +235,21 @@ public:
   
   /*============ Retrieve management: tape server side ======================*/
 
-  
-  class RetrieveMount {};
+  class RetrieveJob;
+  class RetrieveMount {
+  public:
+    struct MountInfo {
+      std::string vid;
+      std::string logicalLibrary;
+      std::string tapePool;
+      std::string drive;
+      uint64_t mountId;
+    } mountInfo;
+    virtual const MountInfo & getMountInfo() = 0;
+    virtual std::unique_ptr<RetrieveJob> getNextJob() = 0;
+    virtual void complete(time_t completionTime) = 0;
+    virtual ~RetrieveMount() {}
+  };
   
   class RetrieveJob {
     friend class RetrieveMount;
@@ -319,7 +332,8 @@ public:
      * lock.
      */
     virtual std::unique_ptr<RetrieveMount> createRetrieveMount(const std::string & vid,
-      const std::string driveName) = 0;
+      const std::string driveName, const std::string& logicalLibrary, 
+      const std::string& hostName, time_t startTime) = 0;
     /** Destructor: releases the global lock if not already done */
     virtual ~TapeMountDecisionInfo() {};
   };
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index 822df5247419461b5d158eb979fb2bf1a33e8585..6d71e18a4c84062260c601d08195d510b2e90141 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -30,6 +30,7 @@
 #include "scheduler/SchedulerDatabase.hpp"
 #include "scheduler/TapeMount.hpp"
 #include "scheduler/ArchiveMount.hpp"
+#include "scheduler/RetrieveMount.hpp"
 #include "common/SecurityIdentity.hpp"
 #include "common/archiveNS/StorageClass.hpp"
 #include "common/archiveNS/Tape.hpp"
@@ -2479,6 +2480,25 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) {
     ASSERT_FALSE(archiveFiles.find("/grandparent/parent_file") ==
       archiveFiles.end());
   }
+  
+  {
+    // Emulate a tape server by asking for a mount and then a file (and succeed
+    // the transfer)
+    std::unique_ptr<cta::TapeMount> mount;
+    /*ASSERT_NO_THROW*/(mount.reset(scheduler.getNextMount(libraryName, "drive0").release()));
+    ASSERT_NE((cta::TapeMount*)NULL, mount.get());
+    ASSERT_EQ(cta::MountType::RETRIEVE, mount.get()->getMountType());
+    std::unique_ptr<cta::RetrieveMount> retrieveMount;
+    ASSERT_NO_THROW(retrieveMount.reset(dynamic_cast<cta::RetrieveMount*>(mount.release())));
+    ASSERT_NE((cta::RetrieveMount*)NULL, retrieveMount.get());
+    std::unique_ptr<cta::RetrieveJob> retrieveJob;
+    ASSERT_NO_THROW(retrieveJob.reset(retrieveMount->getNextJob().release()));
+    ASSERT_NE((cta::RetrieveJob*)NULL, retrieveJob.get());
+    ASSERT_NO_THROW(retrieveJob->complete());
+    ASSERT_NO_THROW(retrieveJob.reset(retrieveMount->getNextJob().release()));
+    ASSERT_EQ((cta::RetrieveJob*)NULL, retrieveJob.get());
+    ASSERT_NO_THROW(retrieveMount->complete());
+  }
 }
 
 TEST_P(SchedulerTest, retrieve_non_existing_file) {
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
index 531e0a242307301c551d0e21401c5bae56e002a6..b959967dc6d02f1affd5ce9a00662c0cf3b8f801 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
@@ -36,13 +36,6 @@
 
 namespace unitTests{
   
-  class TestingArchiveMount: public cta::ArchiveMount {
-  public:
-    TestingArchiveMount(std::unique_ptr<cta::SchedulerDatabase::ArchiveMount> dbrm): 
-      ArchiveMount(*((cta::NameServer *)NULL),std::move(dbrm)) {
-    }
-  };
-  
   class TestingArchiveJob: public cta::ArchiveJob {
   public:
     TestingArchiveJob(): cta::ArchiveJob(*((cta::ArchiveMount *)NULL), 
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTask.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTask.cpp
index c7a6e748261a84f0999980ba759fa3936a64a7c1..255655a56d59f5868274faf08c58c55f1ec86f7d 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTask.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTask.cpp
@@ -120,7 +120,10 @@ bool DiskWriteTask::execute(RecallReportPacker& reporter,log::LogContext& lc,
       }
     } //end of while(1)
     logWithStat(LOG_INFO, "File successfully transfered to disk",lc);
-    reporter.reportCompletedJob(std::move(m_retrieveJob),checksum,m_stats.dataVolume);
+    m_retrieveJob->transferredSize = m_stats.dataVolume;
+    m_retrieveJob->transferredChecksum = cta::Checksum(cta::Checksum::CHECKSUMTYPE_ADLER32, 
+      cta::ByteArray(checksum));
+    reporter.reportCompletedJob(std::move(m_retrieveJob));
     m_stats.waitReportingTime+=localTime.secs(castor::utils::Timer::resetCounter);
     m_stats.transferTime = transferTime.secs();
     m_stats.totalTime = totalTime.secs();
@@ -152,7 +155,8 @@ bool DiskWriteTask::execute(RecallReportPacker& reporter,log::LogContext& lc,
           .add("errorCode", e.code());
     logWithStat(LOG_ERR, "File writing to disk failed.", lc);
     lc.logBacktrace(LOG_ERR, e.backtrace());
-    reporter.reportFailedJob(std::move(m_retrieveJob),e);
+    m_retrieveJob->failureMessage = e.getMessageValue();
+    reporter.reportFailedJob(std::move(m_retrieveJob));
 
     
     //got an exception, return false
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTaskTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTaskTest.cpp
index 59879f9694953b52dff9ca42ec24672d8a64386e..37a83a26e9fa5bf7af7117c5382e5a0a7b68a698 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTaskTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteTaskTest.cpp
@@ -40,6 +40,11 @@
 #include <gtest/gtest.h>
 
 namespace unitTests{
+  class TestingDatabaseRetrieveMount: public cta::SchedulerDatabase::RetrieveMount {
+    virtual const MountInfo & getMountInfo() { throw std::runtime_error("Not implemented"); }
+    virtual std::unique_ptr<cta::SchedulerDatabase::RetrieveJob> getNextJob() { throw std::runtime_error("Not implemented");}
+    virtual void complete(time_t completionTime) { throw std::runtime_error("Not implemented"); }
+  };
   
   class TestingRetrieveMount: public cta::RetrieveMount {
   public:
@@ -78,7 +83,7 @@ namespace unitTests{
     castor::log::StringLogger log("castor_tape_tapeserver_daemon_DiskWriteTaskFailedBlock");
     castor::log::LogContext lc(log);
     
-    std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new cta::SchedulerDatabase::RetrieveMount);
+    std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new TestingDatabaseRetrieveMount());
     TestingRetrieveMount trm(std::move(dbrm));
     MockRecallReportPacker report(&trm,lc);
     EXPECT_CALL(report,reportFailedJob_(_,_));
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteThreadPoolTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteThreadPoolTest.cpp
index 404acfe63b0916628e2992adba55c86c4446b4a3..a3d25962629721237cb2048b7b30d2281c190102 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskWriteThreadPoolTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskWriteThreadPoolTest.cpp
@@ -33,6 +33,12 @@
 
 namespace unitTests{
   
+  class TestingDatabaseRetrieveMount: public cta::SchedulerDatabase::RetrieveMount {
+    virtual const MountInfo & getMountInfo() { throw std::runtime_error("Not implemented"); }
+    virtual std::unique_ptr<cta::SchedulerDatabase::RetrieveJob> getNextJob() { throw std::runtime_error("Not implemented");}
+    virtual void complete(time_t completionTime) { throw std::runtime_error("Not implemented"); }
+  };
+  
   class TestingRetrieveMount: public cta::RetrieveMount {
   public:
     TestingRetrieveMount(std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm): RetrieveMount(std::move(dbrm)) {
@@ -45,6 +51,8 @@ namespace unitTests{
     }
   };
   
+
+  
   using namespace castor::tape::tapeserver::daemon;
   using namespace castor::tape::tapeserver::client;
   struct MockRecallReportPacker : public RecallReportPacker {
@@ -73,7 +81,7 @@ namespace unitTests{
     castor::log::StringLogger log("castor_tape_tapeserver_daemon_DiskWriteThreadPoolTest");
     castor::log::LogContext lc(log);
     
-    std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new cta::SchedulerDatabase::RetrieveMount);
+    std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new TestingDatabaseRetrieveMount);
     TestingRetrieveMount trm(std::move(dbrm));
     MockRecallReportPacker report(&trm,lc);
     
diff --git a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.cpp b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.cpp
index 6af921ace896e46ca6ba781c27892bf2960997be..dba480903f4286fddbd8b8eff137fb8a237638ad 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.cpp
@@ -59,18 +59,16 @@ RecallReportPacker::~RecallReportPacker(){
 //------------------------------------------------------------------------------
 //reportCompletedJob
 //------------------------------------------------------------------------------
-void RecallReportPacker::reportCompletedJob(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob,
-  u_int32_t checksum, u_int64_t size){
-  std::unique_ptr<Report> rep(new ReportSuccessful(std::move(successfulRetrieveJob),checksum,size));
+void RecallReportPacker::reportCompletedJob(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob){
+  std::unique_ptr<Report> rep(new ReportSuccessful(std::move(successfulRetrieveJob)));
   castor::server::MutexLocker ml(&m_producterProtection);
   m_fifo.push(rep.release());
 }
 //------------------------------------------------------------------------------
 //reportFailedJob
 //------------------------------------------------------------------------------  
-void RecallReportPacker::reportFailedJob(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob,
-  const castor::exception::Exception &ex){
-  std::unique_ptr<Report> rep(new ReportError(std::move(failedRetrieveJob),ex));
+void RecallReportPacker::reportFailedJob(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob){
+  std::unique_ptr<Report> rep(new ReportError(std::move(failedRetrieveJob)));
   castor::server::MutexLocker ml(&m_producterProtection);
   m_fifo.push(rep.release());
 }
@@ -94,7 +92,7 @@ void RecallReportPacker::reportEndOfSessionWithErrors(const std::string msg,int
 //ReportSuccessful::execute
 //------------------------------------------------------------------------------
 void RecallReportPacker::ReportSuccessful::execute(RecallReportPacker& parent){
-  m_successfulRetrieveJob->complete(m_checksum, m_size);
+  m_successfulRetrieveJob->complete();
 }
 
 //------------------------------------------------------------------------------
@@ -152,8 +150,8 @@ void RecallReportPacker::ReportEndofSessionWithErrors::execute(RecallReportPacke
 //------------------------------------------------------------------------------
 void RecallReportPacker::ReportError::execute(RecallReportPacker& parent){
   parent.m_errorHappened=true;
-  parent.m_lc.log(LOG_ERR,m_ex.getMessageValue());
-  m_failedRetrieveJob->failed(cta::exception::Exception(m_ex.getMessageValue()));
+  parent.m_lc.log(LOG_ERR,m_failedRetrieveJob->failureMessage);
+  m_failedRetrieveJob->failed();
 }
 //------------------------------------------------------------------------------
 //WorkerThread::WorkerThread
diff --git a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.hpp b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.hpp
index 66acdfe9856d2b7116f98c62f2f9279aa6278f35..b6b69671d9c53683c49b923176fd83e5a23bb689 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPacker.hpp
@@ -54,7 +54,7 @@ public:
    * @param migratedFile the file successfully migrated
    * @param checksum the checksum the DWT has computed for the file 
    */
-  virtual void reportCompletedJob(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob, u_int32_t checksum, u_int64_t size);
+  virtual void reportCompletedJob(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob);
   
   /**
    * Create into the MigrationReportPacker a report for the failed migration
@@ -62,7 +62,7 @@ public:
    * @param migratedFile the file which failed 
    * @param ex the reason for the failure
    */
-  virtual void reportFailedJob(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob, const castor::exception::Exception& ex);
+  virtual void reportFailedJob(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob);
        
   /**
    * Create into the MigrationReportPacker a report for the nominal end of session
@@ -102,30 +102,23 @@ private:
     bool goingToEnd() const {return m_endNear;};
   };
   class ReportSuccessful :  public Report {
-    u_int32_t m_checksum;
-    u_int64_t m_size;
-    
     /**
      * The successful retrieve job to be reported immediately
      */
     std::unique_ptr<cta::RetrieveJob> m_successfulRetrieveJob;
   public:
-    ReportSuccessful(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob,u_int32_t checksum,
-      u_int64_t size): 
-    Report(false),m_checksum(checksum),m_size(size), m_successfulRetrieveJob(std::move(successfulRetrieveJob)){}
+    ReportSuccessful(std::unique_ptr<cta::RetrieveJob> successfulRetrieveJob): 
+    Report(false), m_successfulRetrieveJob(std::move(successfulRetrieveJob)){}
     virtual void execute(RecallReportPacker& reportPacker);
   };
   class ReportError : public Report {
-    const castor::exception::Exception m_ex;
-    
     /**
      * The failed retrieve job to be reported immediately
      */
     std::unique_ptr<cta::RetrieveJob> m_failedRetrieveJob;
   public:
-    ReportError(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob, const castor::exception::Exception &ex):
+    ReportError(std::unique_ptr<cta::RetrieveJob> failedRetrieveJob):
     Report(false),
-    m_ex(ex),
     m_failedRetrieveJob(std::move(failedRetrieveJob)) {
     }
 
diff --git a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPackerTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPackerTest.cpp
index 243e7e45a100d0f6b44da82a4519b7c888ac6de9..0b8383b634c1baf9d3e6049ec324e640f4516c8a 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/RecallReportPackerTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/RecallReportPackerTest.cpp
@@ -118,8 +118,8 @@ TEST_F(castor_tape_tapeserver_daemonTest, RecallReportPackerNominal) {
   castor::tape::tapeserver::daemon::RecallReportPacker rrp(&retrieveMount,lc);
   rrp.startThreads();
 
-  rrp.reportCompletedJob(std::move(job1),0,0);
-  rrp.reportCompletedJob(std::move(job2),0,0);
+  rrp.reportCompletedJob(std::move(job1));
+  rrp.reportCompletedJob(std::move(job2));
 
   rrp.reportEndOfSession();
   rrp.waitThread();
@@ -159,12 +159,13 @@ TEST_F(castor_tape_tapeserver_daemonTest, RecallReportPackerBadBadEnd) {
   castor::tape::tapeserver::daemon::RecallReportPacker rrp(&retrieveMount,lc);
   rrp.startThreads();
 
-  rrp.reportCompletedJob(std::move(job1),0,0);
-  rrp.reportCompletedJob(std::move(job2),0,0);
+  rrp.reportCompletedJob(std::move(job1));
+  rrp.reportCompletedJob(std::move(job2));
 
   const std::string error_msg = "ERROR_TEST_MSG";
   const castor::exception::Exception ex(error_msg);
-  rrp.reportFailedJob(std::move(job3),ex);
+  job3->failureMessage = ex.getMessageValue();
+  rrp.reportFailedJob(std::move(job3));
 
   rrp.reportEndOfSession();
   rrp.waitThread();
diff --git a/tapeserver/castor/tape/tapeserver/file/DiskFile.cpp b/tapeserver/castor/tape/tapeserver/file/DiskFile.cpp
index 19786da31085014eb1b42f95d8c3f17e5af9e8fd..e481013f3f5c3f928ed354beb356adc7dbf195de 100644
--- a/tapeserver/castor/tape/tapeserver/file/DiskFile.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/DiskFile.cpp
@@ -589,7 +589,7 @@ XrootC2FSWriteFile::XrootC2FSWriteFile(const std::string &url,
   m_signedURL = m_URL + opaqueBloc.str();
   
   // ... and finally open the file for write (deleting any existing one in case)
-  XrootClEx::throwOnError(m_xrootFile.Open(m_signedURL, OpenFlags::Delete),
+  XrootClEx::throwOnError(m_xrootFile.Open(m_signedURL, OpenFlags::Delete | OpenFlags::Write),
     std::string("In XrootC2FSWriteFile::XrootC2FSWriteFile failed XrdCl::File::Open() on ")
     +m_URL);
 }
@@ -600,7 +600,7 @@ XrootWriteFile::XrootWriteFile(const std::string& xrootUrl) {
   m_URL = xrootUrl;
   // and simply open
   using XrdCl::OpenFlags;
-  XrootClEx::throwOnError(m_xrootFile.Open(m_URL, OpenFlags::Delete),
+  XrootClEx::throwOnError(m_xrootFile.Open(m_URL, OpenFlags::Delete | OpenFlags::Write),
     std::string("In XrootWriteFile::XrootWriteFile failed XrdCl::File::Open() on ")+m_URL);
 
 }