diff --git a/castor/db/oracleStager.sql b/castor/db/oracleStager.sql
index 29073ff522c92bd420bdca7ce6318386d19b45e6..1bf94ec6be761b139f41369b72cd252685b9b548 100644
--- a/castor/db/oracleStager.sql
+++ b/castor/db/oracleStager.sql
@@ -2834,8 +2834,7 @@ BEGIN
       -- basically only files on tape may be dropped in case no data loss is provoked,
       -- or files already dropped from the namespace. The rest is forbidden.
       IF (varStatus = dconst.DISKCOPY_VALID AND (varNbRemaining > 0 OR varFStatus = 'm'))
-         OR varFStatus = 'd'
-         OR varStatus = dconst.DISKCOPY_FAILED THEN    -- this will eventually disappear
+         OR varFStatus = 'd' THEN
         INSERT INTO DeleteDiskCopyHelper (dcId, rc)
           VALUES (inDcIds(i), dconst.DELDC_GC);
         IF NOT inDryRun THEN
@@ -2858,7 +2857,7 @@ BEGIN
     COMMIT;   -- release locks file by file
   END LOOP;
   -- return back all results for the python script to post-process them,
-  -- including performing all required acations
+  -- including performing all required actions
   OPEN outRes FOR
     SELECT dcId, rc FROM DeleteDiskCopyHelper;
 END;
diff --git a/upgrades/stager_2.1.13-9_to_2.1.14-2.sql b/upgrades/stager_2.1.13-9_to_2.1.14-2.sql
index 1c5645d4f33b8e8123dd182a5129756025ae1d63..89bf33e0df5c88e3f95e90790323d8f31d90ca46 100644
--- a/upgrades/stager_2.1.13-9_to_2.1.14-2.sql
+++ b/upgrades/stager_2.1.13-9_to_2.1.14-2.sql
@@ -179,7 +179,12 @@ CREATE GLOBAL TEMPORARY TABLE DeleteDiskCopyHelper
   (dcId INTEGER CONSTRAINT PK_DDCHelper_dcId PRIMARY KEY, rc INTEGER)
   ON COMMIT PRESERVE ROWS;
 
+ALTER TABLE MigrationJob ADD CONSTRAINT CK_MigrationJob_FS_Positive CHECK (fileSize > 0);
+
+-- Update CastorFile and DiskCopy:
 --  - change the status of diskCopies to merge STAGED and CANBEMIGR
+--  - invalidate existing FAILED
+--  - drop WAITDISK2DISKCOPY
 --  - add a tapeStatus and nsOpenTime to CastorFile
 
 ALTER TABLE CastorFile ADD (tapeStatus INTEGER, nsOpenTime NUMBER);
@@ -188,11 +193,13 @@ DELETE FROM ObjStatus WHERE object='DiskCopy' AND field='status'
 BEGIN setObjStatusName('DiskCopy', 'status', 0, 'DISKCOPY_VALID'); END;
 /
 
+-- temporary index on DiskCopy.status to speed up the next block
+CREATE INDEX I_DC_status ON DiskCopy(status);
 
-ALTER TABLE MigrationJob ADD CONSTRAINT CK_MigrationJob_FS_Positive CHECK (fileSize > 0);
-
-
+DECLARE
+  srIds "numList";
 BEGIN
+  -- merge STAGED and CANBEMIGR
   FOR cf IN (SELECT unique castorFile, status, nbCopies
                FROM DiskCopy, CastorFile, FileClass
               WHERE DiskCopy.castorFile = CastorFile.id
@@ -206,10 +213,23 @@ BEGIN
                                       dconst.CASTORFILE_ONTAPE))
      WHERE id = cf.castorFile;
   END LOOP;
+  UPDATE DiskCopy SET status = dconst.DISKCOPY_VALID WHERE status = 10;
   COMMIT;
+
+  -- invalidate all FAILED diskcopies on disk so that they're properly garbage collected
+  UPDATE DiskCopy SET status = dconst.DISKCOPY_INVALID
+   WHERE status = dconst.DISKCOPY_FAILED AND fileSystem != 0;
+  -- drop all existing WAITDISK2DISKCOPY DiskCopies and fail corresponding requests
+  DELETE FROM DiskCopy WHERE status = dconst.DISKCOPY_WAITDISK2DISKCOPY
+  RETURNING subrequest BULK COLLECT INTO srIds;
+  FORALL i IN srIds.FIRST .. srIds.LAST
+    archiveSubReq(srIds(i), dconst.SUBREQUEST_FAILED_FINISHED);
 END;
 /
 
+-- drop temporary index
+DROP INDEX I_DC_status;
+
 -- temporary function-based index to speed up the following update
 CREATE INDEX I_CF_OpenTimeNull
     ON CastorFile(decode(nvl(nsOpenTime, -1), -1, 1, NULL));
@@ -238,7 +258,7 @@ ALTER TABLE CastorFile MODIFY (nsOpenTime CONSTRAINT NN_CastorFile_NsOpenTime NO
 
 
 ALTER TABLE StageRepackRequest ADD (fileCount INTEGER, totalSize INTEGER);
-UPDATE StageRepackRequest SET fileCount = 0, totalSize = 0;  -- XXX do we need to recompute those figures? probably not...
+UPDATE StageRepackRequest SET fileCount = 0, totalSize = 0;  -- those figures are only used for statistical purposes, assume no need to compute them for existing requests
 ALTER TABLE StageRepackRequest MODIFY (fileCount CONSTRAINT NN_StageRepackReq_fileCount NOT NULL, totalSize CONSTRAINT NN_StageRepackReq_totalSize NOT NULL, status CONSTRAINT NN_StageRepackReq_status NOT NULL, repackVid CONSTRAINT NN_StageRepackReq_repackVid NOT NULL);
 
 DROP TRIGGER tr_DiskCopy_Online;
@@ -281,8 +301,6 @@ ALTER TABLE FileSystem
   ADD CONSTRAINT CK_FileSystem_Status
   CHECK (status IN (0, 1, 2, 3));
 
-XXX Drop all existing WAITDISK2DISKCOPY DiskCopies
-
 ALTER TABLE DiskCopy
   ADD CONSTRAINT CK_DiskCopy_Status
   CHECK (status IN (0, 4, 5, 6, 7, 9, 10, 11));