diff --git a/catalogue/ArchiveFileDoesNotExist.hpp b/catalogue/ArchiveFileDoesNotExist.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e52dc634fd0701d23e3543320cf8c7baabf6fa75
--- /dev/null
+++ b/catalogue/ArchiveFileDoesNotExist.hpp
@@ -0,0 +1,39 @@
+/*
+ * The CERN Tape Archive(CTA) project
+ * Copyright(C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "common/exception/UserError.hpp"
+
+namespace cta {
+
+namespace catalogue {
+
+/**
+ * Archive file does not exist in the CTA catalogue.
+ */
+class ArchiveFileDoesNotExist: public exception::UserError {
+public:
+  /**
+   * The unique identifier of the archive file.
+   */
+  uint64_t archiveFileId;
+};
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp
index 884bfed56d23572637c69c1f586e21df16b3f261..58cac3e562b5f6a008ed0963573ff4e67e11fc24 100644
--- a/catalogue/Catalogue.hpp
+++ b/catalogue/Catalogue.hpp
@@ -18,6 +18,7 @@
 
 #pragma once
 
+#include "catalogue/ArchiveFileDoesNotExist.hpp"
 #include "catalogue/ArchiveFileItor.hpp"
 #include "catalogue/TapeFileSearchCriteria.hpp"
 #include "catalogue/TapeFileWritten.hpp"
@@ -57,6 +58,7 @@
 #include "common/dataStructures/VerifyInfo.hpp"
 #include "common/dataStructures/VidToTapeMap.hpp"
 #include "common/dataStructures/WriteTestResult.hpp"
+#include "common/exception/UserError.hpp"
 
 #include <list>
 #include <map>
@@ -499,6 +501,8 @@ public:
    * @param archiveFileId The unique identifier of the archive file.
    * @return The metadata of the deleted archive file including the metadata of
    * the associated and also deleted tape copies.
+   * @throw ArchiveFileDoesNotExistInCatalogue If the specified archive file
+   * does not exist in the catalogue.
    */
   virtual common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &instanceName, 
     const uint64_t archiveFileId) = 0;
diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp
index 135810f161360ded3f08d955e43fdcd7ffcdd12c..072182d6986c7b4f4799ba958e049f41b4b29f6f 100644
--- a/catalogue/CatalogueTest.cpp
+++ b/catalogue/CatalogueTest.cpp
@@ -6695,7 +6695,7 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_non_existant) {
   using namespace cta;
 
   ASSERT_FALSE(m_catalogue->getArchiveFileItor()->hasMore());
-  ASSERT_THROW(m_catalogue->deleteArchiveFile("disk_instance", 12345678), exception::UserError);
+  ASSERT_THROW(m_catalogue->deleteArchiveFile("disk_instance", 12345678), catalogue::ArchiveFileDoesNotExist);
 }
 
 TEST_P(cta_catalogue_CatalogueTest, getTapesByVid_non_existant_tape) {
diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp
index 3541b1a56e7c3a4533191ac0b29259fe167136db..4b1e89acc8ff2a4385eaa4b15bdce3e353b2d5a1 100644
--- a/catalogue/OracleCatalogue.cpp
+++ b/catalogue/OracleCatalogue.cpp
@@ -128,9 +128,11 @@ common::dataStructures::ArchiveFile OracleCatalogue::deleteArchiveFile(
     }
 
     if(nullptr == archiveFile.get()) {
-      exception::UserError ue;
-      ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because it does not exist";
-      throw ue;
+      ArchiveFileDoesNotExist e;
+      e.archiveFileId = archiveFileId;
+      e.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " from the catalogue because it"
+        " does not exist in the catalogue";
+      throw e;
     }
 
     if(diskInstanceName != archiveFile->diskInstance) {
diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp
index 0811b63acfbdb8d326305dbe8d4f583866e1e5e4..75d06c85855f92b60e6824c6545e6e81d19a2579 100644
--- a/catalogue/OracleCatalogue.hpp
+++ b/catalogue/OracleCatalogue.hpp
@@ -68,6 +68,8 @@ public:
    * @param archiveFileId The unique identifier of the archive file.
    * @return The metadata of the deleted archive file including the metadata of
    * the associated and also deleted tape copies.
+   * @throw ArchiveFileDoesNotExistInCatalogue If the specified archive file
+   * does not exist in the catalogue.
    */
   common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
     const uint64_t archiveFileId) override;
diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp
index e75c1ceef58ea6f89dbed80d6197506cec1e6ecf..dab72ab113cc8c704eea72870c9b3acd48504f15 100644
--- a/catalogue/SqliteCatalogue.cpp
+++ b/catalogue/SqliteCatalogue.cpp
@@ -56,9 +56,11 @@ common::dataStructures::ArchiveFile SqliteCatalogue::deleteArchiveFile(const std
     const auto archiveFile = getArchiveFile(conn, archiveFileId);
 
     if(nullptr == archiveFile.get()) {
-      exception::UserError ue;
-      ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because it does not exist";
-      throw ue;
+      ArchiveFileDoesNotExist e;
+      e.archiveFileId = archiveFileId;
+      e.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " from the catalogue because it"
+        " does not exist in the catalogue";
+      throw e;
     }
 
     if(diskInstanceName != archiveFile->diskInstance) {
diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp
index ce97898f3c6ac5a7120eb13bb2c92aec36047c46..e4708e49535238319e5f682cd8c466c471b36a04 100644
--- a/catalogue/SqliteCatalogue.hpp
+++ b/catalogue/SqliteCatalogue.hpp
@@ -58,6 +58,8 @@ public:
    * @param archiveFileId The unique identifier of the archive file.
    * @return The metadata of the deleted archive file including the metadata of
    * the associated and also deleted tape copies.
+   * @throw ArchiveFileDoesNotExistInCatalogue If the specified archive file
+   * does not exist in the catalogue.
    */
   common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
     const uint64_t archiveFileId) override;
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 38582ff2b913eebe7d78a12350998b57333145c6..b93bc141436f3b804a4db94594bf7cea894852a6 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -216,8 +216,16 @@ common::dataStructures::ArchiveFile Scheduler::deleteArchive(const std::string &
   try {
     m_db.deleteArchiveRequest(instanceName, request.archiveFileID);
   } catch (exception::Exception &dbEx) {
-    // The file was apparently not queued. If we fail to remove it from the catalogue, then it is an error.
-    return m_catalogue.deleteArchiveFile(instanceName, request.archiveFileID);
+    // The file was apparently not queued. If we fail to remove it from the
+    // catalogue for any reason other than it does not exist in the catalogue,
+    // then it is an error.
+    try {
+      return m_catalogue.deleteArchiveFile(instanceName, request.archiveFileID);
+    } catch(catalogue::ArchiveFileDoesNotExist &e) {
+      return common::dataStructures::ArchiveFile();
+    } catch(...) {
+      throw;
+    }
   }
   // We did delete the file from the queue. It hence might be absent from the catalogue.
   // Errors are not fatal here (so we filter them out).