diff --git a/.gitignore b/.gitignore
index e4e879033f1aabee61a25bac4f21cf5a1385d9cf..7a3e1a0e952b69bcfcdb472ad001695cafa8de54 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ cta-release/RPM-GPG-KEY-*
 cta-release/versionlock.cta
 *.swp
 tags
+/.clion.source.upload.marker
diff --git a/catalogue/DriveConfig.cpp b/catalogue/DriveConfig.cpp
index f970b0f02bc90ed1f070def4ee2b0da4ba2ce2f3..8ce0e032937085ef0bd2e4c0f76f349e96de6bc3 100644
--- a/catalogue/DriveConfig.cpp
+++ b/catalogue/DriveConfig.cpp
@@ -28,7 +28,7 @@ namespace cta {
 
 void DriveConfig::setTapedConfiguration(const cta::tape::daemon::TapedConfiguration &tapedConfiguration,
   catalogue::Catalogue* catalogue, const std::string& tapeDriveName) {
-  cta::tape::daemon::TapedConfiguration * config = const_cast<cta::tape::daemon::TapedConfiguration*>(&tapedConfiguration);
+  auto *config = const_cast<cta::tape::daemon::TapedConfiguration *>(&tapedConfiguration);
 
   setConfigToDB(&config->daemonUserName, catalogue, tapeDriveName);
   setConfigToDB(&config->daemonGroupName, catalogue, tapeDriveName);
diff --git a/tapeserver/castor/messages/messages.hpp b/tapeserver/castor/messages/messages.hpp
index 232e7c98093815e2108c99faf78e61daf2b1238a..95603b908cee5b3bf3ca6dee71e6c3b26d7e722b 100644
--- a/tapeserver/castor/messages/messages.hpp
+++ b/tapeserver/castor/messages/messages.hpp
@@ -21,7 +21,6 @@
 #include "castor/messages/Exception.pb.h"
 #include "castor/messages/Frame.hpp"
 #include "castor/messages/Header.pb.h"
-#include "castor/tape/tapeserver/daemon/Constants.hpp"
 #include "common/exception/Exception.hpp"
 
 #include <openssl/rsa.h>
diff --git a/tapeserver/castor/tape/tapeserver/daemon/Constants.hpp b/tapeserver/castor/tape/tapeserver/daemon/Constants.hpp
deleted file mode 100644
index 8f546a76be78179caec9890a9a179d0cb97f44eb..0000000000000000000000000000000000000000
--- a/tapeserver/castor/tape/tapeserver/daemon/Constants.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * @project      The CERN Tape Archive (CTA)
- * @copyright    Copyright © 2021-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 <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-namespace castor     {
-namespace tape       {
-namespace tapeserver {
-namespace daemon     {
-
-/**
- * The TCP/IP port on which the tape server daemon listens for incoming
- * connections and jobs from the VDQM server.
- */
-const unsigned short TAPESERVER_JOB_PORT = 5070;
-
-/**
- * The TCP/IP port on which the tape server daemon listens for incoming
- * connections from the tpconfig admin command.
- */
-const unsigned short TAPESERVER_ADMIN_PORT = 5011;
-
-/**
- * The TCP/IP port on which the tape server daemon listens for incoming
- * connections from the tape labeling command.
- */
-const unsigned short TAPESERVER_LABEL_PORT = 54321;
-
-/**
- * The TCP/IP port on which ZMQ sockets will bind for internal communication
- * between forked sessions and the parent tapeserverd process.
- */
-const unsigned short TAPESERVER_INTERNAL_PORT = 54322;
-
-/**
- * The delay in seconds the master process of the tapeserverd daemon should
- * wait before launching another transfer session whilst the corresponding
- * drive is idle.
- */
-const unsigned int TAPESERVER_TRANSFERSESSION_TIMER = 10;
-
-/**
- * The compile-time default value for the maximum time in seconds that the
- * data-transfer session can take to get the transfer job from the client.
- */
-const time_t TAPESERVER_WAITJOBTIMEOUT = 60; // 1 minute
-
-/** 
- * The compile-time default value for the maximum time in seconds that the
- * data-transfer session can take to mount a tape.
- */
-const time_t TAPESERVER_MOUNTTIMEOUT = 900; // 15 minutes
-
-/**
- * The compile-time default value for the maximum time in seconds the
- * data-transfer session of tapeserverd can cease to move data blocks.
- */
-const time_t TAPESERVER_BLKMOVETIMEOUT = 1800; // 30 minutes
-
-/**
- * The compile-time default value for the number of disk threads in 
- * the thread pool serving disk accesses.
- */
-const uint32_t TAPESERVER_NB_DISK_THREAD = 10;
-
-/**
- * The compile-time default value for the memory buffers exchanged between
- * tape and disk threads.
- */
-const size_t TAPESERVER_BUFSZ = 5 * 1024 * 1024;
-
-/**
- * The compile time timeout value for the potentially DB based calls to the client.
- * As those can take time on a contended and for bulk communications, we go above 
- * the default 20 seconds.
- * This value is not configurable.
- */
-const int TAPESERVER_DB_TIMEOUT = 60 * 5; // 5 minutes
-
-} // namespace daemon
-} // namespace tapeserver
-} // namespace tape
-} // namespace castor
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferConfig.hpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferConfig.hpp
index e89b87fd4b87754adefe03165ed5af1e66e239d7..3f77de93acf855c339fb1929abd736f1e2142620 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferConfig.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferConfig.hpp
@@ -28,7 +28,7 @@ namespace tapeserver {
 namespace daemon {
 
 /**
- * The contents of the castor.conf file to be used by a DataTransferSession.
+ * The contents of the cta.conf file to be used by a DataTransferSession.
  */
 struct DataTransferConfig {
 
@@ -142,11 +142,21 @@ struct DataTransferConfig {
    */
   uint32_t tapeLoadTimeout;
 
+  /**
+   * Maximum time allowed after mounting without a single tape block move
+   */
+  time_t wdNoBlockMoveMaxSecs;
+
+  /**
+   * Time to wait after scheduling came up idle
+   */
+  time_t wdIdleSessionTimer;
+
   /**
    * Constructor that sets all integer member-variables to 0 and all string
    * member-variables to the empty string.
    */
-  DataTransferConfig() throw();
+  DataTransferConfig() noexcept;
 
 }; // DataTransferConfig
 
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
index c7478c87c79e1d9b4c3c9f856074696dbe67d619..a0407c12dd29adb6c7246111d9bb51317caf8117 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
@@ -49,12 +49,12 @@ castor::tape::tapeserver::daemon::DataTransferSession::DataTransferSession(const
                                                                            cta::mediachanger::MediaChangerFacade& mc,
                                                                            cta::tape::daemon::TapedProxy& initialProcess,
                                                                            cta::server::ProcessCap& capUtils,
-                                                                           const DataTransferConfig& castorConf,
+                                                                           const DataTransferConfig& dataTransferConfig,
                                                                            cta::Scheduler& scheduler) :
   m_log(log),
   m_sysWrapper(sysWrapper),
   m_driveConfig(driveConfig),
-  m_castorConf(castorConf),
+  m_dataTransferConfig(dataTransferConfig),
   m_driveInfo({driveConfig.unitName, cta::utils::getShortHostname(), driveConfig.logicalLibrary}),
   m_mediaChanger(mc),
   m_initialProcess(initialProcess),
@@ -184,7 +184,7 @@ castor::tape::tapeserver::daemon::DataTransferSession::execute() {
       // Refresh the status to trigger the timeout update
       m_scheduler.reportDriveStatus(m_driveInfo, cta::common::dataStructures::MountType::NoMount,
                                     cta::common::dataStructures::DriveStatus::Up, lc);
-      sleep(10);
+      sleep(m_dataTransferConfig.wdIdleSessionTimer);
       continue;
     }
     break;
@@ -238,7 +238,7 @@ castor::tape::tapeserver::daemon::DataTransferSession::executeRead(cta::log::Log
   // file to recall.
   // findDrive does not throw exceptions (it catches them to log errors)
   // A nullptr is returned on failure
-  retrieveMount->setExternalFreeDiskSpaceScript(m_castorConf.externalFreeDiskSpaceScript);
+  retrieveMount->setExternalFreeDiskSpaceScript(m_dataTransferConfig.externalFreeDiskSpaceScript);
   std::unique_ptr<castor::tape::tapeserver::drive::DriveInterface> drive(findDrive(logContext, retrieveMount));
 
   if (!drive) {
@@ -251,26 +251,27 @@ castor::tape::tapeserver::daemon::DataTransferSession::executeRead(cta::log::Log
     // to refer them to each other)
     RecallReportPacker reportPacker(retrieveMount, logContext);
     reportPacker.disableBulk(); //no bulk needed anymore
-    RecallWatchDog watchDog(15, 60 * 10, m_initialProcess, *retrieveMount, m_driveConfig.unitName, logContext);
+    RecallWatchDog watchDog(15, m_dataTransferConfig.wdNoBlockMoveMaxSecs, m_initialProcess, *retrieveMount,
+                            m_driveConfig.unitName, logContext);
 
-    RecallMemoryManager memoryManager(m_castorConf.nbBufs, m_castorConf.bufsz, logContext);
+    RecallMemoryManager memoryManager(m_dataTransferConfig.nbBufs, m_dataTransferConfig.bufsz, logContext);
 
     TapeReadSingleThread readSingleThread(*drive, m_mediaChanger, reporter, m_volInfo,
-                                          m_castorConf.bulkRequestRecallMaxFiles, m_capUtils, watchDog, logContext,
+                                          m_dataTransferConfig.bulkRequestRecallMaxFiles, m_capUtils, watchDog, logContext,
                                           reportPacker,
-                                          m_castorConf.useLbp, m_castorConf.useRAO, m_castorConf.useEncryption,
-                                          m_castorConf.externalEncryptionKeyScript, *retrieveMount,
-                                          m_castorConf.tapeLoadTimeout);
+                                          m_dataTransferConfig.useLbp, m_dataTransferConfig.useRAO, m_dataTransferConfig.useEncryption,
+                                          m_dataTransferConfig.externalEncryptionKeyScript, *retrieveMount,
+                                          m_dataTransferConfig.tapeLoadTimeout);
 
-    DiskWriteThreadPool threadPool(m_castorConf.nbDiskThreads,
+    DiskWriteThreadPool threadPool(m_dataTransferConfig.nbDiskThreads,
                                    reportPacker,
                                    watchDog,
                                    logContext,
-                                   m_castorConf.xrootPrivateKey,
-                                   m_castorConf.xrootTimeout);
+                                   m_dataTransferConfig.xrootPrivateKey,
+                                   m_dataTransferConfig.xrootTimeout);
     RecallTaskInjector taskInjector(memoryManager, readSingleThread, threadPool, *retrieveMount,
-                                    m_castorConf.bulkRequestRecallMaxFiles,
-                                    m_castorConf.bulkRequestRecallMaxBytes, logContext);
+                                    m_dataTransferConfig.bulkRequestRecallMaxFiles,
+                                    m_dataTransferConfig.bulkRequestRecallMaxBytes, logContext);
     // Workaround for bug CASTOR-4829: tapegateway: should request positioning by blockid for recalls instead of fseq
     // In order to implement the fix, the task injector needs to know the type of the client
     readSingleThread.setTaskInjector(&taskInjector);
@@ -283,9 +284,9 @@ castor::tape::tapeserver::daemon::DataTransferSession::executeRead(cta::log::Log
     cta::utils::Timer timer;
 
     // The RecallTaskInjector and the TapeReadSingleThread share the promise
-    if (m_castorConf.useRAO) {
-      castor::tape::tapeserver::rao::RAOParams raoDataConfig(m_castorConf.useRAO, m_castorConf.raoLtoAlgorithm,
-                                                             m_castorConf.raoLtoAlgorithmOptions,
+    if (m_dataTransferConfig.useRAO) {
+      castor::tape::tapeserver::rao::RAOParams raoDataConfig(m_dataTransferConfig.useRAO, m_dataTransferConfig.raoLtoAlgorithm,
+                                                             m_dataTransferConfig.raoLtoAlgorithmOptions,
                                                              m_volInfo.vid);
       taskInjector.initRAO(raoDataConfig, &m_scheduler.getCatalogue());
     }
@@ -390,10 +391,11 @@ castor::tape::tapeserver::daemon::DataTransferSession::executeWrite(cta::log::Lo
   {
     //dereferencing configLine is safe, because if configLine were not valid,
     //then findDrive would have return nullptr and we would have not end up there
-    MigrationMemoryManager memoryManager(m_castorConf.nbBufs,
-                                         m_castorConf.bufsz, logContext);
+    MigrationMemoryManager memoryManager(m_dataTransferConfig.nbBufs,
+                                         m_dataTransferConfig.bufsz, logContext);
     MigrationReportPacker reportPacker(archiveMount, logContext);
-    MigrationWatchDog watchDog(15, 60 * 10, m_initialProcess, *archiveMount, m_driveConfig.unitName, logContext);
+    MigrationWatchDog watchDog(15, m_dataTransferConfig.wdNoBlockMoveMaxSecs, m_initialProcess, *archiveMount,
+                               m_driveConfig.unitName, logContext);
     TapeWriteSingleThread writeSingleThread(*drive,
                                             m_mediaChanger,
                                             reporter,
@@ -402,25 +404,25 @@ castor::tape::tapeserver::daemon::DataTransferSession::executeWrite(cta::log::Lo
                                             logContext,
                                             reportPacker,
                                             m_capUtils,
-                                            m_castorConf.maxFilesBeforeFlush,
-                                            m_castorConf.maxBytesBeforeFlush,
-                                            m_castorConf.useLbp,
-                                            m_castorConf.useEncryption,
-                                            m_castorConf.externalEncryptionKeyScript,
+                                            m_dataTransferConfig.maxFilesBeforeFlush,
+                                            m_dataTransferConfig.maxBytesBeforeFlush,
+                                            m_dataTransferConfig.useLbp,
+                                            m_dataTransferConfig.useEncryption,
+                                            m_dataTransferConfig.externalEncryptionKeyScript,
                                             *archiveMount,
-                                            m_castorConf.tapeLoadTimeout);
+                                            m_dataTransferConfig.tapeLoadTimeout);
 
 
-    DiskReadThreadPool threadPool(m_castorConf.nbDiskThreads,
-                                  m_castorConf.bulkRequestMigrationMaxFiles,
-                                  m_castorConf.bulkRequestMigrationMaxBytes,
+    DiskReadThreadPool threadPool(m_dataTransferConfig.nbDiskThreads,
+                                  m_dataTransferConfig.bulkRequestMigrationMaxFiles,
+                                  m_dataTransferConfig.bulkRequestMigrationMaxBytes,
                                   watchDog,
                                   logContext,
-                                  m_castorConf.xrootPrivateKey,
-                                  m_castorConf.xrootTimeout);
+                                  m_dataTransferConfig.xrootPrivateKey,
+                                  m_dataTransferConfig.xrootTimeout);
     MigrationTaskInjector taskInjector(memoryManager, threadPool, writeSingleThread, *archiveMount,
-                                       m_castorConf.bulkRequestMigrationMaxFiles,
-                                       m_castorConf.bulkRequestMigrationMaxBytes, logContext);
+                                       m_dataTransferConfig.bulkRequestMigrationMaxFiles,
+                                       m_dataTransferConfig.bulkRequestMigrationMaxBytes, logContext);
     threadPool.setTaskInjector(&taskInjector);
     writeSingleThread.setTaskInjector(&taskInjector);
     reportPacker.setWatchdog(watchDog);
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
index 6ce7eeb68e06a9d81e730bc8f61c6d8c0af2fc82..f6d0b740b1b2bc8a5d19a8deded5fd9219762fda 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
@@ -55,7 +55,7 @@ public:
                       const cta::tape::daemon::TpconfigLine& driveConfig,
                       cta::mediachanger::MediaChangerFacade& mc,
                       cta::tape::daemon::TapedProxy& initialProcess,
-                      cta::server::ProcessCap& capUtils, const DataTransferConfig& castorConf,
+                      cta::server::ProcessCap& capUtils, const DataTransferConfig& dataTransferConfig,
                       cta::Scheduler& scheduler);
 
   /**
@@ -107,7 +107,7 @@ private:
    * The configuration of the tape drive to be used by this session.
    */
   const cta::tape::daemon::TpconfigLine m_driveConfig;
-  const DataTransferConfig& m_castorConf;
+  const DataTransferConfig& m_dataTransferConfig;
   /**
    * The drive information bundle allowing drive register update.
    * Filled up at construction time.
diff --git a/tapeserver/cta-taped.1cta b/tapeserver/cta-taped.1cta
index be40aa492475aaf69a77869204495c17fa6674ce..e3bdd155e3de17ae2338774a190bc47e01f3e2af 100644
--- a/tapeserver/cta-taped.1cta
+++ b/tapeserver/cta-taped.1cta
@@ -175,12 +175,24 @@ reporting.
 .B taped TapeLoadTimeout \fI300\fR
 Maximum time to wait for a tape to load, in seconds.
 .TP
-.B taped WatchdogScheduleMaxSecs \fI60\fR
+.B taped WatchdogCheckMaxSecs \fI120\fR
+Maximum time allowed to determine a drive is ready, in seconds.
+.TP
+.B taped WatchdogScheduleMaxSecs \fI300\fR
 Maximum time allowed to schedule a single mount, in seconds.
 .TP
-.B taped WatchdogMountMaxSecs \fI900\fR
+.B taped WatchdogMountMaxSecs \fI600\fR
 Maximum time allowed to mount a tape, in seconds.
 .TP
+.B taped WatchdogUnmountMaxSecs \fI600\fR
+Maximum time allowed to unmount a tape, in seconds.
+.TP
+.B taped WatchdogDrainMaxSecs \fI1800\fR
+Maximum time allowed to drain a file to disk during retrieve, in seconds.
+.TP
+.B taped WatchdogShutdownMaxSecs \fI900\fR
+Maximum time allowed to shutdown of a tape session, in seconds.
+.TP
 .B taped WatchdogNoBlockMoveMaxSecs \fI1800\fR
 Maximum time allowed after mounting without any tape blocks being read/written, in seconds. If this
 timeout is exceeded, the session will be terminated.
diff --git a/tapeserver/daemon/DriveHandler.cpp b/tapeserver/daemon/DriveHandler.cpp
index 79530d705dfcdb322496f3fa085b7f0cd7cf67fb..3cf70df3ceffa6fd41830284ba94a8d7695d31e8 100644
--- a/tapeserver/daemon/DriveHandler.cpp
+++ b/tapeserver/daemon/DriveHandler.cpp
@@ -69,7 +69,7 @@ using session::SessionType;
 // (if needed).
 // The session type is not taken into account as a given state gets the same timeout regardless
 // of the type session it is used in.
-const std::map<SessionState, DriveHandler::Timeout> DriveHandler::m_stateChangeTimeouts = {
+std::map<SessionState, DriveHandler::Timeout> DriveHandler::m_stateChangeTimeouts = {
   // Determining the drive is ready takes 1 minute, so waiting 2 should be enough.
   {SessionState::Checking,       std::chrono::duration_cast<Timeout>(std::chrono::minutes(2))},
   // Scheduling is expected to take little time, so 5 minutes is plenty. When the scheduling
@@ -992,18 +992,12 @@ int DriveHandler::runChild() {
 
     castor::tape::tapeserver::daemon::DataTransferConfig dataTransferConfig;
     dataTransferConfig.bufsz = m_tapedConfig.bufferSizeBytes.value();
-    dataTransferConfig.bulkRequestMigrationMaxBytes =
-      m_tapedConfig.archiveFetchBytesFiles.value().maxBytes;
-    dataTransferConfig.bulkRequestMigrationMaxFiles =
-      m_tapedConfig.archiveFetchBytesFiles.value().maxFiles;
-    dataTransferConfig.bulkRequestRecallMaxBytes =
-      m_tapedConfig.retrieveFetchBytesFiles.value().maxBytes;
-    dataTransferConfig.bulkRequestRecallMaxFiles =
-      m_tapedConfig.retrieveFetchBytesFiles.value().maxFiles;
-    dataTransferConfig.maxBytesBeforeFlush =
-      m_tapedConfig.archiveFlushBytesFiles.value().maxBytes;
-    dataTransferConfig.maxFilesBeforeFlush =
-      m_tapedConfig.archiveFlushBytesFiles.value().maxFiles;
+    dataTransferConfig.bulkRequestMigrationMaxBytes = m_tapedConfig.archiveFetchBytesFiles.value().maxBytes;
+    dataTransferConfig.bulkRequestMigrationMaxFiles = m_tapedConfig.archiveFetchBytesFiles.value().maxFiles;
+    dataTransferConfig.bulkRequestRecallMaxBytes = m_tapedConfig.retrieveFetchBytesFiles.value().maxBytes;
+    dataTransferConfig.bulkRequestRecallMaxFiles = m_tapedConfig.retrieveFetchBytesFiles.value().maxFiles;
+    dataTransferConfig.maxBytesBeforeFlush = m_tapedConfig.archiveFlushBytesFiles.value().maxBytes;
+    dataTransferConfig.maxFilesBeforeFlush = m_tapedConfig.archiveFlushBytesFiles.value().maxFiles;
     dataTransferConfig.nbBufs = m_tapedConfig.bufferCount.value();
     dataTransferConfig.nbDiskThreads = m_tapedConfig.nbDiskThreads.value();
     dataTransferConfig.useLbp = true;
@@ -1015,6 +1009,19 @@ int DriveHandler::runChild() {
     dataTransferConfig.xrootPrivateKey = "";
     dataTransferConfig.useEncryption = m_tapedConfig.useEncryption.value() == "yes" ? true : false;
     dataTransferConfig.externalEncryptionKeyScript = m_tapedConfig.externalEncryptionKeyScript.value();
+    dataTransferConfig.wdIdleSessionTimer = m_tapedConfig.wdIdleSessionTimer.value();
+    m_stateChangeTimeouts[session::SessionState::Checking] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdCheckMaxSecs.value()));
+    m_stateChangeTimeouts[session::SessionState::Scheduling] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdScheduleMaxSecs.value()));
+    m_stateChangeTimeouts[session::SessionState::Mounting] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdMountMaxSecs.value()));
+    m_stateChangeTimeouts[session::SessionState::Unmounting] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdUnmountMaxSecs.value()));
+    m_stateChangeTimeouts[session::SessionState::DrainingToDisk] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdDrainMaxSecs.value()));
+    m_stateChangeTimeouts[session::SessionState::ShuttingDown] = std::chrono::duration_cast<Timeout>(
+      std::chrono::minutes(m_tapedConfig.wdShutdownMaxSecs.value()));
 
     // Before launching, and if this is the first session since daemon start, we will
     // put the drive down.
diff --git a/tapeserver/daemon/DriveHandler.hpp b/tapeserver/daemon/DriveHandler.hpp
index 200be6dbe430391223db0b74ef93820eeafe018e..29da50a8a381af2dfe7adc795f7d67896d19e0dd 100644
--- a/tapeserver/daemon/DriveHandler.hpp
+++ b/tapeserver/daemon/DriveHandler.hpp
@@ -134,7 +134,7 @@ private:
   /** Convenience type */
   typedef std::chrono::milliseconds Timeout;
   /** Values for the state change timeouts where applicable */
-  static const std::map<session::SessionState, Timeout> m_stateChangeTimeouts;
+  static std::map<session::SessionState, Timeout> m_stateChangeTimeouts;
   /** Values for the heartbeat timeouts, where applicable */
   static const std::map<session::SessionState, Timeout> m_heartbeatTimeouts;
   /** Values for the data movement timeouts, where applicable */
diff --git a/tapeserver/daemon/TapedConfiguration.hpp b/tapeserver/daemon/TapedConfiguration.hpp
index f747802d038a4a8790e375d8f44a103dc297bd9d..1b14dbd0fd1f8d25c97c34191aa9ee749654aabf 100644
--- a/tapeserver/daemon/TapedConfiguration.hpp
+++ b/tapeserver/daemon/TapedConfiguration.hpp
@@ -110,15 +110,27 @@ struct TapedConfiguration {
   //----------------------------------------------------------------------------
   // Watchdog: parameters for timeouts in various situations.
   //----------------------------------------------------------------------------
-  /// Maximum time allowed to complete a single mount scheduling.
+  /// Maximum time allowed to determine a drive is ready.
+  cta::SourcedParameter<time_t> wdCheckMaxSecs{
+    "taped", "WatchdogCheckMaxSecs", 2 * 60, "Compile time default"};
+  /// Maximum time allowed to schedule a single mount.
   cta::SourcedParameter<time_t> wdScheduleMaxSecs{
-    "taped", "WatchdogScheduleMaxSecs", 60, "Compile time default"};
-  /// Maximum time allowed to complete mount a tape.
+    "taped", "WatchdogScheduleMaxSecs", 5 * 60, "Compile time default"};
+  /// Maximum time allowed to mount a tape.
   cta::SourcedParameter<time_t> wdMountMaxSecs{
-    "taped", "WatchdogMountMaxSecs", 900, "Compile time default"};
+    "taped", "WatchdogMountMaxSecs", 10 * 60, "Compile time default"};
+  /// Maximum time allowed to unmount a tape.
+  cta::SourcedParameter<time_t> wdUnmountMaxSecs{
+    "taped", "WatchdogUnmountMaxSecs", 10 * 60, "Compile time default"};
+  /// Maximum time allowed to drain a file to disk during retrieve.
+  cta::SourcedParameter<time_t> wdDrainMaxSecs{
+    "taped", "WatchdogDrainMaxSecs", 30 * 60, "Compile time default"};
+  /// Maximum time allowed to shutdown of a tape session.
+  cta::SourcedParameter<time_t> wdShutdownMaxSecs{
+    "taped", "WatchdogShutdownMaxSecs", 15 * 60, "Compile time default"};
   /// Maximum time allowed after mounting without a single tape block move
   cta::SourcedParameter<time_t> wdNoBlockMoveMaxSecs{
-    "taped", "WatchdogNoBlockMoveMaxSecs", 1800, "Compile time default"};
+    "taped", "WatchdogNoBlockMoveMaxSecs", 10 * 60, "Compile time default"};
   /// Time to wait after scheduling came up idle
   cta::SourcedParameter<time_t> wdIdleSessionTimer{
     "taped", "WatchdogIdleSessionTimer", 10, "Compile time default"};
diff --git a/tapeserver/daemon/cta-taped.conf.example b/tapeserver/daemon/cta-taped.conf.example
index 84993a42440d1406f07ed794645d53e4c3931eb1..17ef2c9ecd05c452f56cc5834c21cfd9ce53edfb 100644
--- a/tapeserver/daemon/cta-taped.conf.example
+++ b/tapeserver/daemon/cta-taped.conf.example
@@ -156,12 +156,24 @@ taped externalFreeDiskSpaceScript /usr/local/bin/cta-get-free-disk-space.sh
 
 # Maximum time to wait for a tape to load, in seconds.
 # taped TapeLoadTimeout 300
-# 
+#
+# Maximum time allowed to determine a drive is ready, in seconds.
+# taped WatchdogCheckMaxSecs 120
+#
 # Maximum time allowed to schedule a single mount, in seconds.
-# taped WatchdogScheduleMaxSecs 60
-# 
+# taped WatchdogScheduleMaxSecs 300
+#
 # Maximum time allowed to mount a tape, in seconds.
-# taped WatchdogMountMaxSecs 900
+# taped WatchdogMountMaxSecs 600
+#
+# Maximum time allowed to unmount a tape, in seconds.
+# taped WatchdogUnmountMaxSecs 600
+#
+# Maximum time allowed to drain a file to disk during retrieve, in seconds.
+# taped WatchdogDrainMaxSecs 1800
+#
+# Maximum time allowed to shutdown of a tape session, in seconds.
+# taped WatchdogShutdownMaxSecs 900
 # 
 # Maximum time allowed after mounting without any tape blocks being read/written, in seconds.
 # taped WatchdogNoBlockMoveMaxSecs 1800