diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 2cfab53283bbe976dc1a8ed9e48edb951723fab1..7bdf5c98e7a31b5df7139408362cf69d9e7f0553 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -3,6 +3,7 @@
 ## Summary
 
 ### Features
+ - cta/CTA#1016 New options for filtering deleted files using `cta-admin rtf ls` command.
 
 ### Bug fixes
 
diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp
index 22939e944fbe61000fc875207809b65c88f23447..8130a34a02627b8fde1bc6418013e988655bdc73 100644
--- a/catalogue/CatalogueTest.cpp
+++ b/catalogue/CatalogueTest.cpp
@@ -15653,7 +15653,8 @@ TEST_P(cta_catalogue_CatalogueTest, filesArePutInTheFileRecycleLogInsteadOfBeing
     //Check the diskFileId search criteria
     std::string diskFileId = "12345678";
     catalogue::RecycleTapeFileSearchCriteria criteria;
-    criteria.diskFileId = diskFileId;
+    criteria.diskFileIds = std::vector<std::string>();
+    criteria.diskFileIds->push_back(diskFileId);
     auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
     ASSERT_TRUE(fileRecycleLogItor.hasMore());
     auto fileRecycleLog = fileRecycleLogItor.next();
@@ -15664,10 +15665,80 @@ TEST_P(cta_catalogue_CatalogueTest, filesArePutInTheFileRecycleLogInsteadOfBeing
     //Check the non existing diskFileId search criteria
     std::string diskFileId = "DOES_NOT_EXIST";
     catalogue::RecycleTapeFileSearchCriteria criteria;
-    criteria.diskFileId = diskFileId;
+    criteria.diskFileIds = std::vector<std::string>();
+    criteria.diskFileIds->push_back(diskFileId);
     auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
     ASSERT_FALSE(fileRecycleLogItor.hasMore());
   }
+  {
+    //Check the archiveID search criteria
+    uint64_t archiveFileId = 1;
+    catalogue::RecycleTapeFileSearchCriteria criteria;
+    criteria.archiveFileId = archiveFileId;
+    auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
+    ASSERT_TRUE(fileRecycleLogItor.hasMore());
+    auto fileRecycleLog = fileRecycleLogItor.next();
+    ASSERT_EQ(archiveFileId,fileRecycleLog.archiveFileId);
+    ASSERT_FALSE(fileRecycleLogItor.hasMore());
+  }
+  {
+    //Check the non existing archiveFileId search criteria
+    uint64_t archiveFileId = -1;
+    catalogue::RecycleTapeFileSearchCriteria criteria;
+    criteria.archiveFileId = archiveFileId;
+    auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
+    ASSERT_FALSE(fileRecycleLogItor.hasMore());
+  }
+  {
+    //Check the copynb search criteria
+    uint64_t copynb = 1;
+    catalogue::RecycleTapeFileSearchCriteria criteria;
+    criteria.copynb = copynb;
+    auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
+    int nbFileRecycleLogs = 0;
+    while(fileRecycleLogItor.hasMore()){
+      nbFileRecycleLogs++;
+      fileRecycleLogItor.next();
+    }
+    ASSERT_EQ(nbArchiveFiles,nbFileRecycleLogs);
+  }
+  {
+    //Check the disk instance search criteria
+    catalogue::RecycleTapeFileSearchCriteria criteria;
+    criteria.diskInstance = diskInstance;
+    auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
+    int nbFileRecycleLogs = 0;
+    while(fileRecycleLogItor.hasMore()){
+      nbFileRecycleLogs++;
+      fileRecycleLogItor.next();
+    }
+    ASSERT_EQ(nbArchiveFiles,nbFileRecycleLogs);
+  }
+  {
+    //Check multiple search criteria together
+    uint64_t copynb = 1;
+    uint64_t archiveFileId = 1;
+    std::string diskFileId = "12345678";
+    catalogue::RecycleTapeFileSearchCriteria criteria;
+    criteria.diskInstance = diskInstance;
+    criteria.copynb = copynb;
+    criteria.archiveFileId = archiveFileId;
+    criteria.diskFileIds = std::vector<std::string>();
+    criteria.diskFileIds->push_back(diskFileId);
+    criteria.vid = tape1.vid;
+    
+    auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria);
+    
+    ASSERT_TRUE(fileRecycleLogItor.hasMore());
+    auto fileRecycleLog = fileRecycleLogItor.next();
+    ASSERT_EQ(archiveFileId, fileRecycleLog.archiveFileId);
+    ASSERT_EQ(diskFileId, fileRecycleLog.diskFileId);
+    ASSERT_EQ(copynb, fileRecycleLog.copyNb);
+    ASSERT_EQ(tape1.vid, fileRecycleLog.vid);
+    ASSERT_EQ(diskInstance, fileRecycleLog.diskInstanceName);
+    
+    ASSERT_FALSE(fileRecycleLogItor.hasMore());
+  }
 }
 
 TEST_P(cta_catalogue_CatalogueTest, sameFileWrittenToSameTapePutThePreviousCopyOnTheFileRecycleLog) {
diff --git a/catalogue/MysqlCatalogue.cpp b/catalogue/MysqlCatalogue.cpp
index 552bb129738fc641f0fd9894dec7dce33ca8d106..606b5d151a28a9189a845adeffc65050c3419d21 100644
--- a/catalogue/MysqlCatalogue.cpp
+++ b/catalogue/MysqlCatalogue.cpp
@@ -59,10 +59,10 @@ MysqlCatalogue::~MysqlCatalogue() {
 //------------------------------------------------------------------------------
 // createAndPopulateTempTableFxid
 //------------------------------------------------------------------------------
-std::string MysqlCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const {
+std::string MysqlCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const {
   const std::string tempTableName = "TEMP_DISK_FXIDS";
 
-  if(tapeFileSearchCriteria.diskFileIds) {
+  if(diskFileIds) {
     try {
       std::string sql = "CREATE TEMPORARY TABLE " + tempTableName + "(DISK_FILE_ID VARCHAR(100))";
       try {
@@ -76,7 +76,7 @@ std::string MysqlCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, co
 
       sql = "INSERT INTO " + tempTableName + " VALUES(:DISK_FILE_ID)";
       auto stmt = conn.createStmt(sql);
-      for(auto &diskFileId : tapeFileSearchCriteria.diskFileIds.value()) {
+      for(auto &diskFileId : diskFileIds.value()) {
         stmt.bindString(":DISK_FILE_ID", diskFileId);
         stmt.executeNonQuery();
       }
diff --git a/catalogue/MysqlCatalogue.hpp b/catalogue/MysqlCatalogue.hpp
index 1e6b178516ffd0d820f360981e39e882f5e69b07..82d8360bff8be779fec00b01d9d88d7319250037 100644
--- a/catalogue/MysqlCatalogue.hpp
+++ b/catalogue/MysqlCatalogue.hpp
@@ -60,10 +60,10 @@ protected:
    * Creates a temporary table from the list of disk file IDs provided in the search criteria.
    *
    * @param conn The database connection.
-   * @param tapeFileSearchCriteria Search criteria containing a list of disk file IDs (fxid).
+   * @param diskFileIds List of disk file IDs (fxid).
    * @return Name of the temporary table
    */
-  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const override;
+  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const override;
 
   /**
    * Returns a unique archive ID that can be used by a new archive file within
diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp
index 08e63e5afd379df8d58b4a5ee7500276b4ffb9b4..bc1a42c35413ce09523f4e140a1f300d2729a542 100644
--- a/catalogue/OracleCatalogue.cpp
+++ b/catalogue/OracleCatalogue.cpp
@@ -154,11 +154,11 @@ OracleCatalogue::~OracleCatalogue() {
 //------------------------------------------------------------------------------
 // createAndPopulateTempTableFxid
 //------------------------------------------------------------------------------
-std::string OracleCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const {
+std::string OracleCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const {
   const std::string tempTableName = "ORA$PTT_DISK_FXIDS";
 
   try {
-    if(tapeFileSearchCriteria.diskFileIds) {
+    if(diskFileIds) {
       conn.setAutocommitMode(rdbms::AutocommitMode::AUTOCOMMIT_OFF);
       std::string sql = "CREATE PRIVATE TEMPORARY TABLE " + tempTableName +
         "(DISK_FILE_ID VARCHAR2(100))";
@@ -166,7 +166,7 @@ std::string OracleCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, c
   
       sql = "INSERT INTO " + tempTableName + " VALUES(:DISK_FILE_ID)";
       auto stmt = conn.createStmt(sql);
-      for(auto &diskFileId : tapeFileSearchCriteria.diskFileIds.value()) {
+      for(auto &diskFileId : diskFileIds.value()) {
         stmt.bindString(":DISK_FILE_ID", diskFileId);
         stmt.executeNonQuery();
       }
diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp
index 03067d1d544fea1e53e3e4ceccaaaa6bf9459a53..9dd68a65d98cdbd265c41ff005111222151d3610 100644
--- a/catalogue/OracleCatalogue.hpp
+++ b/catalogue/OracleCatalogue.hpp
@@ -61,10 +61,10 @@ public:
    * Creates a temporary table from the list of disk file IDs provided in the search criteria.
    *
    * @param conn The database connection.
-   * @param tapeFileSearchCriteria Search criteria containing a list of disk file IDs (fxid).
+   * @param diskFileIds List of disk file IDs (fxid).
    * @return Name of the temporary table
    */
-  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const override;
+  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const override;
 
   /**
    * Returns a unique archive ID that can be used by a new archive file within
diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp
index da343a4a58d41c7fbe436de4b1856f9a4ed7d32b..3073bb893597fe5b92f161d44736cb24e7547ad0 100644
--- a/catalogue/PostgresCatalogue.cpp
+++ b/catalogue/PostgresCatalogue.cpp
@@ -152,10 +152,10 @@ PostgresCatalogue::~PostgresCatalogue() {
 //------------------------------------------------------------------------------
 // createAndPopulateTempTableFxid
 //------------------------------------------------------------------------------
-std::string PostgresCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const {
+std::string PostgresCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const {
   const std::string tempTableName = "TEMP_DISK_FXIDS";
 
-  if(tapeFileSearchCriteria.diskFileIds) {
+  if(diskFileIds) {
     try {
       std::string sql = "CREATE TEMPORARY TABLE " + tempTableName + "(DISK_FILE_ID VARCHAR(100))";
       try {
@@ -169,7 +169,7 @@ std::string PostgresCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn,
 
       sql = "INSERT INTO " + tempTableName + " VALUES(:DISK_FILE_ID)";
       auto stmt = conn.createStmt(sql);
-      for(auto &diskFileId : tapeFileSearchCriteria.diskFileIds.value()) {
+      for(auto &diskFileId : diskFileIds.value()) {
         stmt.bindString(":DISK_FILE_ID", diskFileId);
         stmt.executeNonQuery();
       }
diff --git a/catalogue/PostgresCatalogue.hpp b/catalogue/PostgresCatalogue.hpp
index ee2c914b851487d39cd5cc307583aacdb1a65fa7..da8d3d6bc4b7f4848b67ebf5e2aa749637640a76 100644
--- a/catalogue/PostgresCatalogue.hpp
+++ b/catalogue/PostgresCatalogue.hpp
@@ -88,10 +88,10 @@ public:
    * Creates a temporary table from the list of disk file IDs provided in the search criteria.
    *
    * @param conn The database connection.
-   * @param tapeFileSearchCriteria Search criteria containing a list of disk file IDs (fxid).
+   * @param diskFileIds List of disk file IDs (fxid).
    * @return Name of the temporary table
    */
-  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const override;
+  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const override;
 
   /**
    * Returns a unique archive ID that can be used by a new archive file within
diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 4db898a66bb1dcd41471ebc6cab0c07c9de163d1..262f58418aa4e506e189a64b7394464713192de5 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -6970,7 +6970,7 @@ Catalogue::ArchiveFileItor RdbmsCatalogue::getArchiveFilesItor(const TapeFileSea
   try {
     // Create a connection to populate the temporary table (specialised by database type)
     auto conn = m_archiveFileListingConnPool.getConn();
-    const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(conn, searchCriteria);
+    const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(conn, searchCriteria.diskFileIds);
     // Pass ownership of the connection to the Iterator object
     auto impl = new RdbmsCatalogueGetArchiveFilesItor(m_log, std::move(conn), searchCriteria, tempDiskFxidsTableName);
     return ArchiveFileItor(impl);
@@ -7002,9 +7002,8 @@ Catalogue::ArchiveFileItor RdbmsCatalogue::getTapeContentsItor(const std::string
 //------------------------------------------------------------------------------
 // checkRecycleTapeFileSearchCriteria
 //------------------------------------------------------------------------------
-void RdbmsCatalogue::checkRecycleTapeFileSearchCriteria(const RecycleTapeFileSearchCriteria & searchCriteria) const {
+void RdbmsCatalogue::checkRecycleTapeFileSearchCriteria(cta::rdbms::Conn &conn, const RecycleTapeFileSearchCriteria & searchCriteria) const {
   if(searchCriteria.vid) {
-    auto conn = m_connPool.getConn();
     if(!tapeExists(conn, searchCriteria.vid.value())) {
       throw exception::UserError(std::string("Tape ") + searchCriteria.vid.value() + " does not exist");
     }
@@ -7013,8 +7012,10 @@ void RdbmsCatalogue::checkRecycleTapeFileSearchCriteria(const RecycleTapeFileSea
 
 Catalogue::FileRecycleLogItor RdbmsCatalogue::getFileRecycleLogItor(const RecycleTapeFileSearchCriteria & searchCriteria) const {
   try {
-    checkRecycleTapeFileSearchCriteria(searchCriteria);
-    auto impl = new RdbmsCatalogueGetFileRecycleLogItor(m_log, m_archiveFileListingConnPool, searchCriteria);
+    auto conn = m_archiveFileListingConnPool.getConn();
+    checkRecycleTapeFileSearchCriteria(conn, searchCriteria);
+    const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(conn, searchCriteria.diskFileIds);
+    auto impl = new RdbmsCatalogueGetFileRecycleLogItor(m_log, std::move(conn), searchCriteria, tempDiskFxidsTableName);
     return FileRecycleLogItor(impl);
   } catch(exception::UserError &) {
     throw;
@@ -7182,7 +7183,7 @@ common::dataStructures::ArchiveFileSummary RdbmsCatalogue::getTapeFileSummary(
       addedAWhereConstraint = true;
     }
     if(searchCriteria.diskFileIds) {
-      const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(conn, searchCriteria);
+      const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(conn, searchCriteria.diskFileIds);
 
       if(addedAWhereConstraint) sql += " AND ";
       sql += "ARCHIVE_FILE.DISK_FILE_ID IN (SELECT DISK_FILE_ID FROM " + tempDiskFxidsTableName + ")";
diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp
index 9b025b28c92c91850c314857fed9ced35f4bff3b..91189898e45ec4a3b1cd6d48da2e2f13651f54de 100644
--- a/catalogue/RdbmsCatalogue.hpp
+++ b/catalogue/RdbmsCatalogue.hpp
@@ -851,10 +851,10 @@ public:
   /**
    * Throws a UserError exception if the specified searchCriteria is not valid
    * due to a user error.
-   *
+   * @param conn The database connection.
    * @param searchCriteria The search criteria.
    */
-  void checkRecycleTapeFileSearchCriteria(const RecycleTapeFileSearchCriteria & searchCriteria) const;
+  void checkRecycleTapeFileSearchCriteria(cta::rdbms::Conn &conn, const RecycleTapeFileSearchCriteria & searchCriteria) const;
   
   /**
    * Returns all the currently deleted files by looking at the FILE_RECYCLE_LOG table
@@ -1575,10 +1575,10 @@ protected:
    * Creates a temporary table from the list of disk file IDs provided in the search criteria.
    *
    * @param conn The database connection.
-   * @param tapeFileSearchCriteria Search criteria containing a list of disk file IDs (fxid).
+   * @param diskFileIds List of disk file IDs (fxid).
    * @return Name of the temporary table
    */
-  virtual std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const = 0;
+  virtual std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const = 0;
 
   /**
    * Returns a unique archive ID that can be used by a new archive file within
diff --git a/catalogue/RdbmsCatalogueGetFileRecycleLogItor.cpp b/catalogue/RdbmsCatalogueGetFileRecycleLogItor.cpp
index ab9b81519cea0155e55f7bf0bcd6bd876141e2eb..71f66cb27fb918d9b66512e0eb22cffddc4c8a85 100644
--- a/catalogue/RdbmsCatalogueGetFileRecycleLogItor.cpp
+++ b/catalogue/RdbmsCatalogueGetFileRecycleLogItor.cpp
@@ -27,10 +27,11 @@ namespace catalogue {
 //------------------------------------------------------------------------------
 RdbmsCatalogueGetFileRecycleLogItor::RdbmsCatalogueGetFileRecycleLogItor(
   log::Logger &log,
-  rdbms::ConnPool &connPool,
-  const RecycleTapeFileSearchCriteria & searchCriteria):
+  rdbms::Conn &&conn,
+  const RecycleTapeFileSearchCriteria & searchCriteria,
+  const std::string &tempDiskFxidsTableName):
   m_log(log),
-  m_connPool(connPool),
+  m_conn(std::move(conn)),
   m_searchCriteria(searchCriteria),
   m_rsetIsEmpty(true),
   m_hasMoreHasBeenCalled(false) {
@@ -65,7 +66,10 @@ RdbmsCatalogueGetFileRecycleLogItor::RdbmsCatalogueGetFileRecycleLogItor(
 
     const bool thereIsAtLeastOneSearchCriteria =
       searchCriteria.vid            ||
-      searchCriteria.diskFileId;
+      searchCriteria.diskFileIds    ||
+      searchCriteria.archiveFileId  ||
+      searchCriteria.copynb         ||
+      searchCriteria.diskInstance;
 
     if(thereIsAtLeastOneSearchCriteria) {
       sql += " WHERE ";
@@ -77,12 +81,29 @@ RdbmsCatalogueGetFileRecycleLogItor::RdbmsCatalogueGetFileRecycleLogItor(
       sql += "FILE_RECYCLE_LOG.VID = :VID";
       addedAWhereConstraint = true;
     }
+
+    if (searchCriteria.archiveFileId) {
+      if(addedAWhereConstraint) sql += " AND ";
+      sql += "FILE_RECYCLE_LOG.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
+      addedAWhereConstraint = true;
+    }
     
-    if(searchCriteria.diskFileId){
+    if(searchCriteria.diskFileIds) {
       if(addedAWhereConstraint) sql += " AND ";
-      sql += "FILE_RECYCLE_LOG.DISK_FILE_ID = :DISK_FILE_ID";
+      sql += "FILE_RECYCLE_LOG.DISK_FILE_ID IN (SELECT DISK_FILE_ID FROM " + tempDiskFxidsTableName + ")";
       addedAWhereConstraint = true;
     }
+
+    if (searchCriteria.diskInstance) {
+      if(addedAWhereConstraint) sql += " AND ";
+      sql += "FILE_RECYCLE_LOG.DISK_INSTANCE_NAME = :DISK_INSTANCE";
+      addedAWhereConstraint = true;
+    }
+
+    if (searchCriteria.copynb) {
+      if(addedAWhereConstraint) sql += " AND ";
+      sql += "FILE_RECYCLE_LOG.COPY_NB = :COPY_NB";
+    }
     
     // Order by FSEQ if we are listing the contents of a tape, else order by archive file ID
     if(searchCriteria.vid) {
@@ -91,15 +112,22 @@ RdbmsCatalogueGetFileRecycleLogItor::RdbmsCatalogueGetFileRecycleLogItor(
       sql += " ORDER BY FILE_RECYCLE_LOG.ARCHIVE_FILE_ID, FILE_RECYCLE_LOG.COPY_NB";
     }
     
-    m_conn = connPool.getConn();
     m_stmt = m_conn.createStmt(sql);
     
     if(searchCriteria.vid){
       m_stmt.bindString(":VID", searchCriteria.vid.value());
     }
-    
-    if(searchCriteria.diskFileId){
-      m_stmt.bindString(":DISK_FILE_ID", searchCriteria.diskFileId.value());
+
+    if (searchCriteria.archiveFileId) {
+      m_stmt.bindUint64(":ARCHIVE_FILE_ID", searchCriteria.archiveFileId.value());
+    }
+
+    if (searchCriteria.diskInstance) {
+      m_stmt.bindString(":DISK_INSTANCE", searchCriteria.diskInstance.value());
+    }
+
+    if (searchCriteria.copynb) {
+      m_stmt.bindUint64(":COPY_NB", searchCriteria.copynb.value());
     }
     
     m_rset = m_stmt.executeQuery();
diff --git a/catalogue/RdbmsCatalogueGetFileRecycleLogItor.hpp b/catalogue/RdbmsCatalogueGetFileRecycleLogItor.hpp
index c94cfe3949fa916190a23e0c55ca9ff4e01f993a..90e996b82ed39506e25cc28634f225bd7106d5b6 100644
--- a/catalogue/RdbmsCatalogueGetFileRecycleLogItor.hpp
+++ b/catalogue/RdbmsCatalogueGetFileRecycleLogItor.hpp
@@ -29,9 +29,13 @@ public:
    * Constructor.
    *
    * @param log Object representing the API to the CTA logging system.
-   * @param connPool The database connection pool.
+   * @param conn A database connection.
    */
-  RdbmsCatalogueGetFileRecycleLogItor(log::Logger &log, rdbms::ConnPool &connPool, const RecycleTapeFileSearchCriteria & searchCriteria);
+  RdbmsCatalogueGetFileRecycleLogItor(
+    log::Logger &log, 
+    rdbms::Conn &&conn, 
+    const RecycleTapeFileSearchCriteria & searchCriteria, 
+    const std::string &tempDiskFxidsTableName);
 
   /**
    * Destructor.
@@ -54,10 +58,12 @@ private:
    */
   log::Logger &m_log;
 
+
   /**
-   * The database connection pool.
+   * The database connection.
    */
-  rdbms::ConnPool &m_connPool;
+  rdbms::Conn m_conn;
+
   
   /**
    * The search criteria to be used when listing recycled tape files.
@@ -79,11 +85,6 @@ private:
    */
   bool m_hasMoreHasBeenCalled;
 
-  /**
-   * The database connection.
-   */
-  rdbms::Conn m_conn;
-
   /**
    * The database statement.
    */
diff --git a/catalogue/RecyleTapeFileSearchCriteria.hpp b/catalogue/RecyleTapeFileSearchCriteria.hpp
index 8fc49830645e51f08c5c95006a235c8491ff22a3..eb4ab60cb73af6c73b9d52a7895e0082adad13ac 100644
--- a/catalogue/RecyleTapeFileSearchCriteria.hpp
+++ b/catalogue/RecyleTapeFileSearchCriteria.hpp
@@ -32,6 +32,15 @@ namespace catalogue {
  * Please note that no wild cards, for example '*' or '%', are supported.
  */
 struct RecycleTapeFileSearchCriteria {
+  /**
+   * The unique identifier of an archive file.
+   */
+  optional<uint64_t> archiveFileId;
+
+  /**
+   * The name of a disk instance.
+   */
+  optional<std::string> diskInstance;
   
   /**
    * The volume identifier of a tape.
@@ -44,7 +53,12 @@ struct RecycleTapeFileSearchCriteria {
    * These are given as a list of strings in DECIMAL format. EOS provides the fxids in hex format. The parsing and
    * conversion into decimal is done in the cta-admin client, ready to be built into a SQL query string.
    */
-  optional<std::string> diskFileId;
+  optional<std::vector<std::string>> diskFileIds;
+
+  /**
+   * The copy number of the deleted tape file.
+   */
+  optional<uint64_t> copynb;
   
 }; // struct TapeFileSearchCriteria
 
diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp
index c809025876f84e27a19ee67f5141488b3046009c..a48071da05e08c5d310537bb35f20d4bfd0730e9 100644
--- a/catalogue/SqliteCatalogue.cpp
+++ b/catalogue/SqliteCatalogue.cpp
@@ -192,7 +192,7 @@ void SqliteCatalogue::DO_NOT_USE_deleteArchiveFile_DO_NOT_USE(const std::string
 //------------------------------------------------------------------------------
 // createAndPopulateTempTableFxid
 //------------------------------------------------------------------------------
-std::string SqliteCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const {
+std::string SqliteCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const {
   try {
     const std::string tempTableName = "TEMP.DISK_FXIDS";
 
@@ -200,9 +200,9 @@ std::string SqliteCatalogue::createAndPopulateTempTableFxid(rdbms::Conn &conn, c
     conn.executeNonQuery("DROP TABLE IF EXISTS " + tempTableName);
     conn.executeNonQuery("CREATE TEMPORARY TABLE " + tempTableName + "(DISK_FILE_ID TEXT)");
 
-    if(tapeFileSearchCriteria.diskFileIds) {
+    if(diskFileIds) {
       auto stmt = conn.createStmt("INSERT INTO " + tempTableName + " VALUES(:DISK_FILE_ID)");
-      for(auto &diskFileId : tapeFileSearchCriteria.diskFileIds.value()) {
+      for(auto &diskFileId : diskFileIds.value()) {
         stmt.bindString(":DISK_FILE_ID", diskFileId);
         stmt.executeNonQuery();
       }
diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp
index 020589f930823f08d39bd77e288d0a703a3a11a6..f42f9f14ca63c487be216d2f9d6365da1c3f3279 100644
--- a/catalogue/SqliteCatalogue.hpp
+++ b/catalogue/SqliteCatalogue.hpp
@@ -86,10 +86,10 @@ protected:
    * Creates a temporary table from the list of disk file IDs provided in the search criteria.
    *
    * @param conn The database connection.
-   * @param tapeFileSearchCriteria Search criteria containing a list of disk file IDs (fxid).
+   * @param diskFileIds List of disk file IDs (fxid).
    * @return Name of the temporary table
    */
-  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const TapeFileSearchCriteria &tapeFileSearchCriteria) const override;
+  std::string createAndPopulateTempTableFxid(rdbms::Conn &conn, const optional<std::vector<std::string>> &diskFileIds) const override;
 
   /**
    * Returns a unique archive ID that can be used by a new archive file within
diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp
index 70b6123de3d2a67a453fdecac8e0321c38022608..da06f29a18b63aff72bcedd4b2c0148beffd201b 100644
--- a/cmdline/CtaAdminCmdParse.hpp
+++ b/cmdline/CtaAdminCmdParse.hpp
@@ -408,7 +408,7 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = {
    { AdminCmd::CMD_VERSION,              { "version",               "v",  { } }},
    { AdminCmd::CMD_SCHEDULINGINFOS,      { "schedulinginfo",        "si",  { "ls" } }},
    { AdminCmd::CMD_RECYCLETAPEFILE,      { "recycletf",        "rtf",  { "ls" },
-                            "  Tape files in the recycle log can be listed by VID or by EOS disk file ID.\n"
+                            "  Tape files in the recycle log can be listed by VID, EOS disk file ID, EOS disk instance, ArchiveFileId or copy number.\n"
                             "  Disk file IDs should be provided in hexadecimal (fxid).\n\n" }},
 };
 
@@ -614,7 +614,8 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
       { }},
    {{ AdminCmd::CMD_VERSION,           AdminCmd::SUBCMD_NONE   }, { }},
    {{ AdminCmd::CMD_SCHEDULINGINFOS,      AdminCmd::SUBCMD_LS   }, { }},
-   {{ AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_LS }, { opt_vid.optional(), opt_fid.optional() }},
+   {{ AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_LS }, 
+   { opt_vid.optional(), opt_fid.optional(), opt_fidfile.optional(), opt_copynb.optional(), opt_archivefileid.optional(), opt_instance.optional() }},
 };
 
 
diff --git a/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp b/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp
index 7c18034dd8eadefad9f2c83c39860beb5237ab7b..86631b2386d39813e1ae2c644cf76feed24f8d23 100644
--- a/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp
+++ b/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp
@@ -66,15 +66,28 @@ RecycleTapeFileLsStream::RecycleTapeFileLsStream(const RequestMessage &requestMs
   searchCriteria.vid = requestMsg.getOptional(OptionString::VID, &has_any);
   
   auto diskFileId = requestMsg.getOptional(OptionString::FXID, &has_any);
+
+  searchCriteria.diskFileIds = requestMsg.getOptional(OptionStrList::FILE_ID, &has_any);
   
   if(diskFileId){
     // single option on the command line we need to do the conversion ourselves.
+    if(!searchCriteria.diskFileIds) searchCriteria.diskFileIds = std::vector<std::string>();
+
     auto fid = strtol(diskFileId->c_str(), nullptr, 16);
     if(fid < 1 || fid == LONG_MAX) {
        throw cta::exception::UserError(*diskFileId + " is not a valid file ID");
     }
-    searchCriteria.diskFileId = std::to_string(fid);
+
+    searchCriteria.diskFileIds->push_back(std::to_string(fid));
   }
+  // Disk instance on its own does not give a valid set of search criteria (no &has_any)
+  searchCriteria.diskInstance = requestMsg.getOptional(OptionString::INSTANCE);
+
+  searchCriteria.archiveFileId = requestMsg.getOptional(OptionUInt64::ARCHIVE_FILE_ID, &has_any);
+
+  // Copy number on its own does not give a valid set of search criteria (no &has_any)
+  searchCriteria.copynb = requestMsg.getOptional(OptionUInt64::COPY_NUMBER);
+
   if(!has_any){
     throw cta::exception::UserError("Must specify at least one search option");
   }
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
index 24bf193b2872f6bb74bf26c0636b7dd15cdf9de5..846024bb659c3f0ec1a6aec4d57a3f1231185759 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
@@ -207,7 +207,7 @@ private:
   void processVirtualOrganization_Add(cta::xrd::Response &response);
   void processVirtualOrganization_Ch(cta::xrd::Response &response);
   void processVirtualOrganization_Rm(cta::xrd::Response &response);
-
+  
   /*!
    * Process AdminCmd events which can return a stream response
    *