diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index db60caae162dcde8258331223ac58b792fcbc207..672c15c97d3d56b65f56716e350129f122ce7765 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -6,6 +6,7 @@
 - cta/CTA#641 - Archive workflow of Postgres Scheduler DB can write a file to tape
 - cta/CTA#257 - Allow CTA CI runner to use MHVTL ULTRIUM config
 - cta/CTA#667 - Sonarcloud code smells in catalogue
+- cta/CTA#670 - Add the ability to read EnstoreLarge tapes
 
 ### Bug Fixes
 - cta/CTA#485 - Check disk file metadata on delete requests
diff --git a/common/dataStructures/LabelFormat.hpp b/common/dataStructures/LabelFormat.hpp
index 36dbb5c81eb531be26a4f3fe433847533b95629e..6744d0cd4d5dbd0dcf409b248dbc5d394ef97125 100644
--- a/common/dataStructures/LabelFormat.hpp
+++ b/common/dataStructures/LabelFormat.hpp
@@ -30,7 +30,8 @@ struct Label {
   enum class Format : std::uint8_t {
     CTA = 0x00,
     OSM = 0x01,
-    Enstore = 0x02
+    Enstore = 0x02, 
+    EnstoreLarge = 0x03
   };
 
   static Format validateFormat(const std::optional<std::uint8_t>& ouiFormat, const std::string& strContext) {
@@ -43,6 +44,7 @@ struct Label {
       case Format::CTA:
       case Format::OSM:
       case Format::Enstore:
+      case Format::EnstoreLarge:
         return format;
       default:
       {
diff --git a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
index 7b54085692b04fbc5ed017413724c1e668dad5ef..a4a6c5cb7e3e58352f5cb1354bcf09a1d985aef3 100644
--- a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
+++ b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
@@ -35,6 +35,8 @@ set(TAPESERVER_FILE_LIBRARY_SRCS
   OsmReadSession.cpp
   EnstoreFileReader.cpp
   EnstoreReadSession.cpp
+  EnstoreLargeFileReader.cpp
+  EnstoreLargeReadSession.cpp
   OsmFileStructure.cpp
   CpioFileHeaderStructure.cpp
   ReadSession.cpp
diff --git a/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.cpp b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fed4472c7f0925529c375cb050344c4e8b4ac2fe
--- /dev/null
+++ b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.cpp
@@ -0,0 +1,193 @@
+/*
+ * @project      The CERN Tape Archive (CTA)
+ * @copyright    Copyright © 2022 CERN
+ * @license      This program is free software, distributed under the terms of the GNU General Public
+ *               Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can
+ *               redistribute it and/or modify it under the terms of the GPL Version 3, 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.
+ *
+ *               In applying this licence, CERN does not waive the privileges and immunities
+ *               granted to it by virtue of its status as an Intergovernmental Organization or
+ *               submit itself to any jurisdiction.
+ */
+
+#include <limits>
+#include <memory>
+#include <sstream>
+#include <string>
+
+#include "castor/tape/tapeserver/drive/DriveInterface.hpp"
+#include "castor/tape/tapeserver/file/CtaReadSession.hpp"
+#include "castor/tape/tapeserver/file/EnstoreLargeFileReader.hpp"
+#include "castor/tape/tapeserver/file/HeaderChecker.hpp"
+#include "castor/tape/tapeserver/file/Structures.hpp"
+#include "scheduler/RetrieveJob.hpp"
+
+namespace castor::tape::tapeFile {
+
+EnstoreLargeFileReader::EnstoreLargeFileReader(ReadSession& rs, const cta::RetrieveJob& fileToRecall) :
+FileReader(rs, fileToRecall) {
+  setPositioningMethod(cta::PositioningMethod::ByFSeq);  // Enstore did not store block IDs
+}
+
+void EnstoreLargeFileReader::setPositioningMethod(const cta::PositioningMethod& newMethod) {
+  m_positionCommandCode = newMethod;
+}
+
+void EnstoreLargeFileReader::positionByFseq(const cta::RetrieveJob& fileToRecall) {
+  if (m_session.getCurrentFilePart() != PartOfFile::Header) {
+    m_session.setCorrupted();
+    throw SessionCorrupted();
+  }
+  // Make sure the session state is advanced to cover our failures
+  // and allow next call to position to discover we failed half way
+  m_session.setCurrentFilePart(PartOfFile::HeaderProcessing);
+
+  if (fileToRecall.selectedTapeFile().fSeq < 1) {
+    std::ostringstream err;
+    err << std::string(__FUNCTION__) << ": "
+        << "Unexpected fileId. fSeq expected >=1, got: " << fileToRecall.selectedTapeFile().fSeq << ")";
+    throw cta::exception::InvalidArgument(err.str());
+  }
+
+  const int64_t fSeq_delta =
+    static_cast<int64_t>(fileToRecall.selectedTapeFile().fSeq) - static_cast<int64_t>(m_session.getCurrentFseq());
+  moveReaderByFSeqDelta(fSeq_delta);  // Let's just try this
+  checkHeaders(fileToRecall);
+}
+
+void EnstoreLargeFileReader::positionByBlockID(const cta::RetrieveJob& fileToRecall) {
+  throw NotImplemented(
+    "EnstoreLargeFileReader::positionByBlockID() Cannot be implemented. Enstore did not store block IDs");
+}
+
+void EnstoreLargeFileReader::setBlockSize(const UHL1& uhl1) {  // Could inherit
+  m_currentBlockSize = static_cast<size_t>(atol(uhl1.getBlockSize().c_str()));
+  if (m_currentBlockSize < 1) {
+    std::ostringstream ex_str;
+    ex_str << std::string(__FUNCTION__) << ": "
+           << "Invalid block size in uhl1 detected";
+    throw TapeFormatError(ex_str.str());
+  }
+}
+
+size_t EnstoreLargeFileReader::readNextDataBlock(void* data, const size_t size) {
+  if (size != m_currentBlockSize) {
+    throw WrongBlockSize();
+  }
+  size_t bytes_read = m_session.m_drive.readBlock(data, size);
+  // end of file reached! we will keep on reading until we have read the file mark at the end of the trailers
+  if (!bytes_read) {
+    checkTrailers();
+    // the following is a normal day exception: end of files exceptions are thrown at the end of each file being read
+    throw EndOfFile();
+  }
+  return bytes_read;
+}
+
+void EnstoreLargeFileReader::moveToFirstHeaderBlock() {
+  throw NotImplemented("EnstoreLargeFileReader::moveToFirstHeaderBlock() Not implemented.");
+}
+
+void EnstoreLargeFileReader::moveReaderByFSeqDelta(const int64_t fSeq_delta) {
+  if (fSeq_delta == 0) {
+    // do nothing we are in the correct place
+  }
+  else if (fSeq_delta > 0) {
+    // we need to skip three file marks per file (header, payload, trailer)
+    m_session.m_drive.spaceFileMarksForward(static_cast<uint32_t>(fSeq_delta) * 3);
+  }
+  else {  // fSeq_delta < 0
+    // we need to skip three file marks per file
+    // (trailer, payload, header) + 1 to go on the BOT (beginning of tape) side
+    // of the file mark before the header of the file we want to read
+    m_session.m_drive.spaceFileMarksBackwards(static_cast<uint32_t>(std::abs(fSeq_delta)) * 3 + 1);
+    m_session.m_drive.readFileMark(std::string(__FUNCTION__) + ": " +
+                                   "Reading file mark right before the header of the file we want to read");
+  }
+}
+
+void EnstoreLargeFileReader::checkTrailers() {
+  m_session.setCurrentFilePart(PartOfFile::Trailer);
+
+  // let's read and check the trailers
+
+  size_t blockSize = 256 * 1024;
+  char* data = new char[blockSize + 1];
+  size_t bytes_read = m_session.m_drive.readBlock(data, blockSize);
+
+  EOF1 eof1;
+  EOF2 eof2;
+  UTL1 utl1;
+
+  if (bytes_read < sizeof(eof1) + sizeof(eof2) + sizeof(utl1)) {
+    throw cta::exception::Exception(std::string(__FUNCTION__) +
+                                    " failed: Too few bytes read for headers:" + std::to_string(bytes_read));
+  }
+  memcpy(&eof1, data, sizeof(eof1));
+  memcpy(&eof2, data + sizeof(eof1), sizeof(eof2));
+  memcpy(&utl1, data + sizeof(eof1) + sizeof(eof2), sizeof(utl1));
+  delete[] data;
+
+  m_session.m_drive.readFileMark(std::string(__FUNCTION__) + ": " + "Reading file mark at the end of file header");
+
+  m_session.setCurrentFseq(m_session.getCurrentFseq() + 1);  // moving on to the header of the next file
+  m_session.setCurrentFilePart(PartOfFile::Header);
+
+  // the size of the headers is fine, now let's check each header
+  try {
+    eof1.verify(true);  // Skip certain field where enstore and CTA don't match
+    eof2.verify("D");  
+    utl1.verify();
+  }
+  catch (std::exception& e) {
+    throw TapeFormatError(e.what());
+  }
+}
+
+void EnstoreLargeFileReader::checkHeaders(const cta::RetrieveJob& fileToRecall) {
+  // save the current fSeq into the read session
+  m_session.setCurrentFseq(fileToRecall.selectedTapeFile().fSeq);
+
+  size_t blockSize = 256 * 1024;
+  char* data = new char[blockSize + 1];
+  size_t bytes_read = m_session.m_drive.readBlock(data, blockSize);
+
+  HDR1 hdr1;
+  HDR2 hdr2;
+  UHL1 uhl1;
+
+  if (bytes_read < sizeof(hdr1) + sizeof(hdr2) + sizeof(uhl1)) {
+    throw cta::exception::Exception(std::string(__FUNCTION__) +
+                                    " failed: Too few bytes read for headers:" + std::to_string(bytes_read));
+  }
+  memcpy(&hdr1, data, sizeof(hdr1));
+  memcpy(&hdr2, data + sizeof(hdr1), sizeof(hdr1));
+  memcpy(&uhl1, data + sizeof(hdr1) + sizeof(hdr2), sizeof(uhl1));
+  delete[] data;
+
+  m_session.m_drive.readFileMark(std::string(__FUNCTION__) + ": " + "Reading file mark at the end of file header");
+  // after this we should be where we want, i.e. at the beginning of the file
+  m_session.setCurrentFilePart(PartOfFile::Payload);
+
+  // the size of the headers is fine, now let's check each header
+  // Extend these with skipped things for Fermilab tapes
+  try {
+    hdr1.verify(true);  // Skip certain field where enstore and CTA don't match
+    hdr2.verify("D");  
+    uhl1.verify();
+  }
+  catch (std::exception& e) {
+    throw TapeFormatError(e.what());
+  }
+
+  // This differs from CTA checkHeaders in that none of the checks in checkHDR1 or checkUHL1
+  // works for these Enstore tapes. We skip this entirely but get the block size out of UHL1
+  setBlockSize(uhl1);
+}
+
+}  // namespace castor::tape::tapeFile
diff --git a/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.hpp b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e81ca883eca3be31bf3e1f2e940cb062bb5dea70
--- /dev/null
+++ b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeFileReader.hpp
@@ -0,0 +1,62 @@
+/*
+ * @project      The CERN Tape Archive (CTA)
+ * @copyright    Copyright © 2022 CERN
+ * @license      This program is free software, distributed under the terms of the GNU General Public
+ *               Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can
+ *               redistribute it and/or modify it under the terms of the GPL Version 3, 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.
+ *
+ *               In applying this licence, CERN does not waive the privileges and immunities
+ *               granted to it by virtue of its status as an Intergovernmental Organization or
+ *               submit itself to any jurisdiction.
+ */
+
+#pragma once
+
+#include <fstream>
+#include <memory>
+
+#include "castor/tape/tapeserver/file/CpioFileHeaderStructure.hpp"
+#include "castor/tape/tapeserver/file/FileReader.hpp"
+
+namespace castor::tape::tapeFile {
+
+class UHL1;
+
+class EnstoreLargeFileReader : public FileReader {
+public:
+  CTA_GENERATE_EXCEPTION_CLASS(NotImplemented);
+
+  /**
+   * Constructor
+   *
+   * It will bind itself to an existing read session and position the tape right at the beginning of the file
+   *
+   * @param rs           session to bind to
+   * @param fileToRecall the file which will be recalled
+   */
+  EnstoreLargeFileReader(ReadSession& rs, const cta::RetrieveJob& fileToRecall);
+
+  /**
+    * Destructor of the FileReader. It will release the lock on the read session.
+    */
+  ~EnstoreLargeFileReader() override = default;
+
+  size_t readNextDataBlock(void* data, const size_t size) override;
+
+private:
+  void setPositioningMethod(const cta::PositioningMethod& newMethod);
+  void positionByFseq(const cta::RetrieveJob& fileToRecall) override;
+  void positionByBlockID(const cta::RetrieveJob& fileToRecall) override;
+  void setBlockSize(const UHL1& uhl1);
+  void moveToFirstHeaderBlock();  // Not implemented
+  void moveReaderByFSeqDelta(const int64_t fSeq_delta);
+  void checkHeaders(const cta::RetrieveJob& fileToRecall);
+  void checkTrailers();
+};
+
+}  // namespace castor::tape::tapeFile
diff --git a/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.cpp b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f15ecf36cab6d90064b5d2a67ed4c1baeb45a132
--- /dev/null
+++ b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.cpp
@@ -0,0 +1,65 @@
+/*
+ * @project      The CERN Tape Archive (CTA)
+ * @copyright    Copyright © 2022 CERN
+ * @license      This program is free software, distributed under the terms of the GNU General Public
+ *               Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can
+ *               redistribute it and/or modify it under the terms of the GPL Version 3, 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.
+ *
+ *               In applying this licence, CERN does not waive the privileges and immunities
+ *               granted to it by virtue of its status as an Intergovernmental Organization or
+ *               submit itself to any jurisdiction.
+ */
+
+#include <memory>
+#include <string>
+
+#include "castor/tape/tapeserver/file/Exceptions.hpp"
+#include "castor/tape/tapeserver/file/HeaderChecker.hpp"
+#include "castor/tape/tapeserver/file/EnstoreLargeReadSession.hpp"
+#include "castor/tape/tapeserver/file/Structures.hpp"
+#include "common/exception/Exception.hpp"
+
+namespace castor::tape::tapeFile {
+
+EnstoreLargeReadSession::EnstoreLargeReadSession(tapeserver::drive::DriveInterface& drive,
+                                                 const tapeserver::daemon::VolumeInfo& volInfo,
+                                                 const bool useLbp) :
+ReadSession(drive, volInfo, useLbp) {
+  m_drive.rewind();
+  m_drive.disableLogicalBlockProtection();
+  m_detectedLbp = false;
+
+  VOL1 vol1;
+
+  // VOL1 on the EnstoreLarge tapes is longer than the existing ones.
+  // Throw away the end and validate the beggining as a normal VOL1
+  size_t blockSize = 256 * 1024;
+  char* data = new char[blockSize + 1];
+  size_t bytes_read = m_drive.readBlock(data, blockSize);
+  if (bytes_read < sizeof(vol1)) {
+    throw cta::exception::Exception(std::string(__FUNCTION__) + " failed: Too few bytes read from label");
+  }
+  memcpy(&vol1, data, sizeof(vol1));
+  delete[] data;
+
+  // Tapes should have label character 3, but if they were recycled from CPIO tapes, it could be 0
+  try {
+    vol1.verify("3");
+  } catch (std::exception& e) {
+    try {
+      vol1.verify("0");
+    } catch (std::exception& e) {
+      throw TapeFormatError(e.what());
+    };
+  };
+  HeaderChecker::checkVOL1(vol1, volInfo.vid);
+  // after which we are at the end of VOL1 header (e.g. beginning of first file)
+  m_drive.readFileMark(std::string(__FUNCTION__) + " failed: Reading filemark");
+}
+
+}  // namespace castor::tape::tapeFile
diff --git a/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.hpp b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ea85cdc75ae17bf31e7bd43c66b6ed33b59e28ac
--- /dev/null
+++ b/tapeserver/castor/tape/tapeserver/file/EnstoreLargeReadSession.hpp
@@ -0,0 +1,51 @@
+/*
+ * @project      The CERN Tape Archive (CTA)
+ * @copyright    Copyright © 2022 CERN
+ * @license      This program is free software, distributed under the terms of the GNU General Public
+ *               Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can
+ *               redistribute it and/or modify it under the terms of the GPL Version 3, 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.
+ *
+ *               In applying this licence, CERN does not waive the privileges and immunities
+ *               granted to it by virtue of its status as an Intergovernmental Organization or
+ *               submit itself to any jurisdiction.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "castor/tape/tapeserver/daemon/VolumeInfo.hpp"
+#include "castor/tape/tapeserver/file/ReadSession.hpp"
+
+namespace castor::tape::tapeFile {
+
+/**
+  * Class keeping track of a whole tape read session over an Enstore formatted
+  * tape. The session will keep track of the overall coherency of the session
+  * and check for everything to be coherent. The tape should be mounted in
+  * the drive before the EnstoreReadSession is started (i.e. constructed).
+  * Likewise, tape unmount is the business of the user.
+  */
+class EnstoreLargeReadSession : public ReadSession {
+public:
+  /**
+    * Constructor of the EnstoreReadSession. It will rewind the tape, and check the
+    * VID value. Throws an exception in case of mismatch.
+    * @param drive: drive object to which we bind the session
+    * @param volInfo: volume name of the tape we would like to read from
+    * @param useLbp: castor.conf option to use or not to use LBP in tapeserverd
+    */
+  EnstoreLargeReadSession(tapeserver::drive::DriveInterface& drive,
+                          const tapeserver::daemon::VolumeInfo& volInfo,
+                          const bool useLbp);
+
+  ~EnstoreLargeReadSession() override = default;
+};
+
+}  // namespace castor::tape::tapeFile
diff --git a/tapeserver/castor/tape/tapeserver/file/EnstoreReadSession.cpp b/tapeserver/castor/tape/tapeserver/file/EnstoreReadSession.cpp
index 2dbb8fd3c1d293624c0e12c30991df5eb2943f24..1a0a37c38ddc3176cad4f6c89e0571df4e67f77c 100644
--- a/tapeserver/castor/tape/tapeserver/file/EnstoreReadSession.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/EnstoreReadSession.cpp
@@ -34,11 +34,16 @@ EnstoreReadSession::EnstoreReadSession(tapeserver::drive::DriveInterface &drive,
 
   VOL1 vol1;
   m_drive.readExactBlock(reinterpret_cast<void *>(&vol1), sizeof(vol1), "[ReadSession::ReadSession()] - Reading VOL1");
+  // Tapes should have label character 0, but if they were recycled from EnstoreLarge tapes, it could be 3
   try {
     vol1.verify("0");
-  } catch (std::exception &e) {
-    throw TapeFormatError(e.what());
-  }
+  } catch (std::exception& e) {
+    try {
+      vol1.verify("3");
+    } catch (std::exception& e) {
+      throw TapeFormatError(e.what());
+    };
+  };
   HeaderChecker::checkVOL1(vol1, volInfo.vid);
   // after which we are at the end of VOL1 header (e.g. beginning of first file)
 
diff --git a/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp b/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp
index 08bd5dc539f1691f601bd17468863d5119292ff9..6104ab784649c39d009a41a3eec4149a8b1b6d25 100644
--- a/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp
@@ -20,6 +20,7 @@
 
 #include "castor/tape/tapeserver/file/CtaFileReader.hpp"
 #include "castor/tape/tapeserver/file/EnstoreFileReader.hpp"
+#include "castor/tape/tapeserver/file/EnstoreLargeFileReader.hpp"
 #include "castor/tape/tapeserver/file/FileReaderFactory.hpp"
 #include "castor/tape/tapeserver/file/OsmFileReader.hpp"
 #include "castor/tape/tapeserver/file/ReadSession.hpp"
@@ -44,6 +45,10 @@ std::unique_ptr<FileReader> FileReaderFactory::create(ReadSession& readSession,
       reader = std::make_unique<EnstoreFileReader>(readSession, fileToRecall);
       break;
     }
+    case LabelFormat::EnstoreLarge: {
+      reader = std::make_unique<EnstoreLargeFileReader>(readSession, fileToRecall);
+      break;
+    }
     default: {
       std::ostringstream ossLabelFormat;
       ossLabelFormat << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(4)
diff --git a/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp b/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp
index 971582af4fbe76ef496f50077a4fa18066a86c78..d84b2cce8bea7e4e96bb2b49c6ccb07092715e93 100644
--- a/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp
@@ -20,6 +20,7 @@
 
 #include "castor/tape/tapeserver/file/CtaReadSession.hpp"
 #include "castor/tape/tapeserver/file/EnstoreReadSession.hpp"
+#include "castor/tape/tapeserver/file/EnstoreLargeReadSession.hpp"
 #include "castor/tape/tapeserver/file/OsmReadSession.hpp"
 #include "castor/tape/tapeserver/file/ReadSessionFactory.hpp"
 #include "common/dataStructures/LabelFormat.hpp"
@@ -37,6 +38,8 @@ std::unique_ptr<ReadSession> ReadSessionFactory::create(tapeserver::drive::Drive
       return std::make_unique<OsmReadSession>(drive, volInfo, useLbp);
     case LabelFormat::Enstore:
       return std::make_unique<EnstoreReadSession>(drive, volInfo, useLbp);
+    case LabelFormat::EnstoreLarge:
+      return std::make_unique<EnstoreLargeReadSession>(drive, volInfo, useLbp);
     default: {
       std::ostringstream ossLabelFormat;
       ossLabelFormat << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(4)
diff --git a/tapeserver/castor/tape/tapeserver/file/Structures.cpp b/tapeserver/castor/tape/tapeserver/file/Structures.cpp
index a5cb83d490d3a535230d129c8af21255f7da611f..62021831b31b2ababe6465d2c7303f34402e2751 100644
--- a/tapeserver/castor/tape/tapeserver/file/Structures.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/Structures.cpp
@@ -82,7 +82,7 @@ void tapeFile::HDR1EOF1::fillCommon(std::string fileId, std::string VSN, int fSe
   setString(m_sysCode, std::string("CTA ") + CTA_VERSION);
 }
 
-void tapeFile::HDR1EOF1::verifyCommon()
+void tapeFile::HDR1EOF1::verifyCommon(const bool skipFSecCheck)
   const  {
 
   if (!cmpString(m_fileId, ""))
@@ -92,10 +92,12 @@ void tapeFile::HDR1EOF1::verifyCommon()
   if (!cmpString(m_VSN, ""))
     throw cta::exception::Exception(std::string("Failed verify for the VSN: ") +
           tapeFile::toString(m_VSN));
-  if (cmpString(m_fSec, "0001"))
-    throw cta::exception::Exception(
-          std::string("Failed verify for the fSec: ") +
-          tapeFile::toString(m_fSec));
+  if (!skipFSecCheck) {
+    if (cmpString(m_fSec, "0001"))
+      throw cta::exception::Exception(
+            std::string("Failed verify for the fSec: ") +
+            tapeFile::toString(m_fSec));
+  };
   if (!cmpString(m_fSeq, ""))
     throw cta::exception::Exception(
           std::string("Failed verify for the fSeq: ") +
@@ -137,7 +139,7 @@ void tapeFile::HDR1::fill(
   fillCommon(fileId, VSN, fSeq);
 }
 
-void tapeFile::HDR1::verify() const  {
+void tapeFile::HDR1::verify(const bool skipFSecCheck) const  {
   if (cmpString(m_label, "HDR1"))
     throw cta::exception::Exception(std::string("Failed verify for the HDR1: ") +
           tapeFile::toString(m_label));
@@ -145,7 +147,7 @@ void tapeFile::HDR1::verify() const  {
     throw cta::exception::Exception(std::string("Failed verify for the blockCount: ") +
           tapeFile::toString(m_blockCount));
 
-  verifyCommon();
+  verifyCommon(skipFSecCheck);
 }
 
 void tapeFile::HDR1PRELABEL::fill(std::string VSN) {
@@ -182,7 +184,7 @@ void tapeFile::EOF1::fill(
   fillCommon(fileId, VSN, fSeq);
 }
 
-void tapeFile::EOF1::verify() const  {
+void tapeFile::EOF1::verify(const bool skipFSecCheck) const  {
   if (cmpString(m_label, "EOF1"))
     throw cta::exception::Exception(std::string("Failed verify for the EOF1: ") +
           tapeFile::toString(m_label));
@@ -191,7 +193,7 @@ void tapeFile::EOF1::verify() const  {
           std::string("Failed verify for the blockCount: ") +
           tapeFile::toString(m_blockCount));
 
-  verifyCommon();
+  verifyCommon(skipFSecCheck);
 }
 
 void tapeFile::HDR2EOF2::fillCommon(int blockLength, bool driveHasCompression) {
@@ -207,12 +209,13 @@ void tapeFile::HDR2EOF2::fillCommon(int blockLength, bool driveHasCompression) {
   setString(m_aulId, "00");
 }
 
-void tapeFile::HDR2EOF2::verifyCommon() 
+void tapeFile::HDR2EOF2::verifyCommon(const char *const formatCharacter) 
   const  {
-  if (cmpString(m_recordFormat, "F"))
+  if (cmpString(m_recordFormat, formatCharacter)) {
     throw cta::exception::Exception(
           std::string("Failed verify for the recordFormat: ") +
           tapeFile::toString(m_recordFormat));
+  };
   if (!cmpString(m_blockLength, ""))
     throw cta::exception::Exception(
           std::string("Failed verify for the blockLength: ") +
@@ -238,12 +241,12 @@ void tapeFile::HDR2::fill(int blockLength, bool driveHasCompression) {
   
   fillCommon(blockLength, driveHasCompression);
 }
-void tapeFile::HDR2::verify() const  {
+void tapeFile::HDR2::verify(const char *const formatCharacter) const  {
   if (cmpString(m_label, "HDR2"))
     throw cta::exception::Exception(std::string("Failed verify for the HDR2: ") +
           tapeFile::toString(m_label));
 
-  verifyCommon();
+  verifyCommon(formatCharacter);
 }
 
 void tapeFile::EOF2::fill(int blockLength, bool driveHasCompression) {
@@ -252,12 +255,12 @@ void tapeFile::EOF2::fill(int blockLength, bool driveHasCompression) {
   fillCommon(blockLength, driveHasCompression);
 }
 
-void tapeFile::EOF2::verify() const  {
+void tapeFile::EOF2::verify(const char *const formatCharacter) const  {
   if (cmpString(m_label, "EOF2"))
     throw cta::exception::Exception(std::string("Failed verify for the EOF2: ") +
           tapeFile::toString(m_label));
 
-  verifyCommon();
+  verifyCommon(formatCharacter);
 }
 
 void tapeFile::UHL1UTL1::fillCommon(int fSeq,
diff --git a/tapeserver/castor/tape/tapeserver/file/Structures.hpp b/tapeserver/castor/tape/tapeserver/file/Structures.hpp
index 22b8220fd334d81dc9c41306b33a413fc02e7196..6f18271b57d13361ce9a31a11521b7274d5286a2 100644
--- a/tapeserver/castor/tape/tapeserver/file/Structures.hpp
+++ b/tapeserver/castor/tape/tapeserver/file/Structures.hpp
@@ -165,7 +165,7 @@ namespace castor::tape::tapeFile {
        * Throws an exception if the common field of the structures does
        * not match expectations.
        */
-      void verifyCommon() const ;
+      void verifyCommon(const bool skipFSecCheck = false) const ;
     public:
 
       /**
@@ -212,7 +212,7 @@ namespace castor::tape::tapeFile {
       /**
        * Throws an exception if the structure does not match expectations.
        */
-      void verify() const ;
+      void verify(const bool skipFSecCheck = false) const ;
     };
 
     class EOF1 : public HDR1EOF1 {
@@ -233,7 +233,7 @@ namespace castor::tape::tapeFile {
       /**
        * Throws an exception if the structure does not match expectations.
        */
-      void verify() const ;
+      void verify(const bool skipFSecCheck = false) const ;
     };
     
     class HDR1PRELABEL : public HDR1EOF1 {
@@ -286,7 +286,7 @@ namespace castor::tape::tapeFile {
       /**
        * Throws an exception if the structure does not match expectations.
        */
-      void verifyCommon() const ;
+      void verifyCommon(const char *const formatCharacter = "F") const ;
     public:
       /**
        * @return    The block length 
@@ -312,7 +312,7 @@ namespace castor::tape::tapeFile {
       /**
        * Throws an exception if the structure does not match expectations.
        */
-      void verify() const ;
+      void verify(const char *const formatCharacter = "F") const ;
     };
 
     class EOF2 : public HDR2EOF2 {
@@ -331,7 +331,7 @@ namespace castor::tape::tapeFile {
       /**
        * Throws an exception if the structure does not match expectations.
        */
-      void verify() const ;
+      void verify(const char *const formatCharacter = "F") const ;
     };
 
     // The common part of the UHL1 and UTL1 labels