diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 426fd54b826b2ff8cb2a76ca36b9516825839598..5a84c9e51d90bd64f76a0f1e961c754979ad0207 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -317,6 +317,22 @@ void Scheduler::queueLabel(const common::dataStructures::SecurityIdentity &cliId
   throw exception::Exception(std::string("Not implemented: ") + __PRETTY_FUNCTION__);
 }
 
+void Scheduler::checkTapeFullBeforeRepack(std::string vid){
+  std::set<std::string> vidToRepack;
+  vidToRepack.insert(vid);
+  try{
+    auto vidToTapesMap = m_catalogue.getTapesByVid(vidToRepack); //throws an exception if the vid is not found on the database
+    cta::common::dataStructures::Tape tapeToCheck = vidToTapesMap.at(vid);
+    if(!tapeToCheck.full){
+      throw exception::UserError("You must set the tape as full before repacking it.");
+    }
+  } catch(const exception::UserError& userEx){
+    throw userEx;
+  } catch(const cta::exception::Exception & ex){
+    throw exception::UserError("The VID provided for repacking does not exist");
+  }
+}
+
 //------------------------------------------------------------------------------
 // repack
 //------------------------------------------------------------------------------
@@ -326,6 +342,7 @@ void Scheduler::queueRepack(const common::dataStructures::SecurityIdentity &cliI
   if (vid.empty()) throw exception::UserError("Empty VID name.");
   if (bufferURL.empty()) throw exception::UserError("Empty buffer URL.");
   utils::Timer t;
+  checkTapeFullBeforeRepack(vid);
   m_db.queueRepack(vid, bufferURL, repackType, lc);
   log::TimingList tl;
   tl.insertAndReset("schedulerDbTime", t);
diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp
index dfa184e7a8dd5f2a19b3ed41ceb7474445795110..fd5422b7d13a311bce3b4fc8c9405a64025edbf8 100644
--- a/scheduler/Scheduler.hpp
+++ b/scheduler/Scheduler.hpp
@@ -308,6 +308,13 @@ private:
     std::map<tpType, uint32_t> & existingMountsSummary, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList,
     double & getTapeInfoTime, double & candidateSortingTime, double & getTapeForWriteTime, log::LogContext & lc);
   
+  /**
+   * Checks wether the tape is full before repacking
+   * @param vid the vid of the tape to check
+   * @throws a UserError exception if the vid does not exist or if
+   * the tape is not full
+   */
+  void checkTapeFullBeforeRepack(std::string vid);
   
 public:
   /**
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index f9e4300fde22abd902ea554a65b14baece4599d5..3067e541ae811a8175c9a2cd399127a319de6f68 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -1254,16 +1254,35 @@ TEST_P(SchedulerTest, repack) {
   setupDefaultCatalogue();
   
   Scheduler &scheduler = getScheduler();
-  
+  cta::catalogue::Catalogue& catalogue = getCatalogue();
+    
   log::DummyLogger dl("", "");
   log::LogContext lc(dl);
   
   typedef cta::common::dataStructures::RepackInfo RepackInfo;
   typedef cta::common::dataStructures::RepackInfo::Status Status;
   
-  // Create and then cancel repack
+   // Create the environment for the migration to happen (library + tape) 
+  const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
+    libraryIsDisabled, libraryComment);
+  
   common::dataStructures::SecurityIdentity cliId;
+  cliId.host = "host";
+  cliId.username = s_userName;
   std::string tape1 = "Tape";
+  
+  catalogue.createTape(cliId,tape1,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,false,"Comment");
+  
+  //The queueing of a repack request should fail if the tape to repack is not full
+  ASSERT_THROW(scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc),cta::exception::UserError);
+  //The queueing of a repack request in a vid that does not exist should throw an exception
+  ASSERT_THROW(scheduler.queueRepack(cliId, "NOT_EXIST", "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc),cta::exception::UserError);
+  
+  catalogue.setTapeFull(cliId,tape1,true);
+  
+  // Create and then cancel repack
   scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   {
     auto repacks = scheduler.getRepacks();
@@ -1274,12 +1293,14 @@ TEST_P(SchedulerTest, repack) {
   scheduler.cancelRepack(cliId, tape1, lc);
   ASSERT_EQ(0, scheduler.getRepacks().size());
   // Recreate a repack and get it moved to ToExpand
-  scheduler.queueRepack(cliId, "Tape2", "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
+  std::string tape2 = "Tape2";
+  catalogue.createTape(cliId,tape2,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  scheduler.queueRepack(cliId, tape2, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   {
     auto repacks = scheduler.getRepacks();
     ASSERT_EQ(1, repacks.size());
     auto repack = scheduler.getRepack(repacks.front().vid);
-    ASSERT_EQ("Tape2", repack.vid);
+    ASSERT_EQ(tape2, repack.vid);
   }
   scheduler.promoteRepackRequestsToToExpand(lc);
   {
@@ -1296,16 +1317,30 @@ TEST_P(SchedulerTest, getNextRepackRequestToExpand) {
   setupDefaultCatalogue();
   
   Scheduler &scheduler = getScheduler();
+  catalogue::Catalogue& catalogue = getCatalogue();
   
   log::DummyLogger dl("", "");
   log::LogContext lc(dl);
   
-  // Create a repack request
+  // Create the environment for the migration to happen (library + tape) 
+  const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
+    libraryIsDisabled, libraryComment);
+  
   common::dataStructures::SecurityIdentity cliId;
+  cliId.host = "host";
+  cliId.username = s_userName;
   std::string tape1 = "Tape";
+  catalogue.createTape(cliId,tape1,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  
+  //Queue the first repack request
   scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   
   std::string tape2 = "Tape2";
+  catalogue.createTape(cliId,tape2,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  
+  //Queue the second repack request
   scheduler.queueRepack(cliId,tape2,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::AddCopiesOnly,lc);
   
   //Test the repack request queued has status Pending
@@ -1361,7 +1396,7 @@ TEST_P(SchedulerTest, expandRepackRequest) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1697,7 +1732,7 @@ TEST_P(SchedulerTest, expandRepackRequestRetrieveFailed) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1937,7 +1972,7 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1954,6 +1989,10 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
   std::string vid = ossVid.str();
   catalogue.createTape(s_adminOnAdminHost,vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
+  //Create a repack destination tape
+  std::string vidDestination = "vidDestination";
+  catalogue.createTape(s_adminOnAdminHost,vidDestination, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
+    disabledValue, false, comment);
   
   //Create a storage class in the catalogue
   common::dataStructures::StorageClass storageClass;
@@ -2184,7 +2223,7 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveFailed) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -2201,6 +2240,11 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveFailed) {
   std::string vid = ossVid.str();
   catalogue.createTape(s_adminOnAdminHost,vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
+
+  //Create a repack destination tape
+  std::string vidDestinationRepack = "vidDestinationRepack";
+  catalogue.createTape(s_adminOnAdminHost,vidDestinationRepack, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
+   disabledValue, false, comment);
   
   //Create a storage class in the catalogue
   common::dataStructures::StorageClass storageClass;
@@ -2484,7 +2528,7 @@ TEST_P(SchedulerTest, expandRepackRequestExpansionTimeLimitReached) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";