diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp
index 305f75ce995cb64863e0d80d67ff819164273a0c..f202e917b5c24c6a007de3828c60e4d3358d41dc 100644
--- a/catalogue/Catalogue.hpp
+++ b/catalogue/Catalogue.hpp
@@ -245,6 +245,16 @@ public:
   virtual void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) = 0;
   virtual void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const std::string &comment) = 0;
 
+  /**
+   * Modifies the name of the specified storage class.
+   *
+   * @param diskInstanceName The name of the disk instance to which the
+   * storage class belongs.
+   * @param currentName The current name of the storage class.
+   * @param newName The new name of the storage class.
+   */
+  virtual void modifyStorageClassName(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &currentName, const std::string &newName) = 0;
+
   virtual void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) = 0;
   virtual void deleteTapePool(const std::string &name) = 0;
   virtual std::list<TapePool> getTapePools() const = 0;
diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp
index 4e78ae7a54f301030ec8408dfb9dca749e8e8c08..bea781fa14008ebc01b1dd38788f20b6231082a0 100644
--- a/catalogue/CatalogueRetryWrapper.hpp
+++ b/catalogue/CatalogueRetryWrapper.hpp
@@ -137,6 +137,10 @@ public:
     return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyStorageClassComment(admin, instanceName, name, comment);}, m_maxTriesToConnect);
   }
 
+  void modifyStorageClassName(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &currentName, const std::string &newName) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyStorageClassName(admin, instanceName, currentName, newName);}, m_maxTriesToConnect);
+  }
+
   void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) override {
     return retryOnLostConnection(m_log, [&]{return m_catalogue->createTapePool(admin, name, vo, nbPartialTapes, encryptionValue, supply, comment);}, m_maxTriesToConnect);
   }
diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp
index 9fcf23f773b1c6e9ed4fcef9a3829e439aadaada..1b787e44167ad96188a19229440b251803055a8e 100644
--- a/catalogue/CatalogueTest.cpp
+++ b/catalogue/CatalogueTest.cpp
@@ -797,6 +797,67 @@ TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassComment_nonExistentStorage
     exception::UserError);
 }
 
+TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassName) {
+  using namespace cta;
+
+  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());
+
+  common::dataStructures::StorageClass storageClass;
+  storageClass.diskInstance = "disk_instance";
+  storageClass.name = "storage_class";
+  storageClass.nbCopies = 2;
+  storageClass.comment = "Create storage class";
+  m_catalogue->createStorageClass(m_admin, storageClass);
+
+  {
+    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();
+
+    ASSERT_EQ(1, storageClasses.size());
+
+    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
+    ASSERT_EQ(storageClass.name, storageClasses.front().name);
+    ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
+    ASSERT_EQ(storageClass.comment, storageClasses.front().comment);
+
+    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+
+    const common::dataStructures::EntryLog lastModificationLog = storageClasses.front().lastModificationLog;
+    ASSERT_EQ(creationLog, lastModificationLog);
+  }
+
+  const std::string newStorageClassName = "new_storage_class_name";
+  m_catalogue->modifyStorageClassName(m_admin, storageClass.diskInstance, storageClass.name, newStorageClassName);
+
+  {
+    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();
+
+    ASSERT_EQ(1, storageClasses.size());
+
+    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
+    ASSERT_EQ(newStorageClassName, storageClasses.front().name);
+    ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
+    ASSERT_EQ(storageClass.comment, storageClasses.front().comment);
+
+    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  }
+}
+
+TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassName_nonExistentStorageClass) {
+  using namespace cta;
+
+  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());
+
+  const std::string diskInstance = "disk_instance";
+  const std::string currentStorageClassName = "storage_class";
+  const std::string newStorageClassName = "new_storage_class";
+  ASSERT_THROW(m_catalogue->modifyStorageClassName(m_admin, diskInstance, currentStorageClassName, newStorageClassName),
+    exception::UserError);
+}
+
 TEST_P(cta_catalogue_CatalogueTest, createTapePool) {
   using namespace cta;
       
diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp
index b314e32ed2e8d9b9f30ff534970a3cf8c9d5076e..1e6111dfd332b48b95115e07f278354e8509ba0a 100644
--- a/catalogue/DummyCatalogue.hpp
+++ b/catalogue/DummyCatalogue.hpp
@@ -92,6 +92,7 @@ public:
   void modifyRequesterGroupMountRulePolicy(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& requesterGroupName, const std::string& mountPolicy) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyRequesterMountRulePolicy(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& requesterName, const std::string& mountPolicy) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyStorageClassComment(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void modifyStorageClassName(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& currentName, const std::string& newName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& name, const uint64_t nbCopies) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyTapeCapacityInBytes(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const uint64_t capacityInBytes) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyTapeComment(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 663a2c33d6809c01991d3d8757d8ffce7457416e..4b2d2ec5019dac393ebbe6dfb934eb80c12d6cc5 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -632,6 +632,44 @@ void RdbmsCatalogue::modifyStorageClassComment(const common::dataStructures::Sec
   }
 }
 
+//------------------------------------------------------------------------------
+// modifyStorageClassName
+//------------------------------------------------------------------------------
+void RdbmsCatalogue::modifyStorageClassName(const common::dataStructures::SecurityIdentity &admin,
+  const std::string &instanceName, const std::string &currentName, const std::string &newName) {
+  try {
+    const time_t now = time(nullptr);
+    const char *const sql =
+      "UPDATE STORAGE_CLASS SET "
+        "STORAGE_CLASS_NAME = :NEW_STORAGE_CLASS_NAME,"
+        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
+        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
+        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
+      "WHERE "
+        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
+        "STORAGE_CLASS_NAME = :CURRENT_STORAGE_CLASS_NAME";
+    auto conn = m_connPool.getConn();
+    auto stmt = conn.createStmt(sql);
+    stmt.bindString(":NEW_STORAGE_CLASS_NAME", newName);
+    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
+    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
+    stmt.bindUint64(":LAST_UPDATE_TIME", now);
+    stmt.bindString(":DISK_INSTANCE_NAME", instanceName);
+    stmt.bindString(":CURRENT_STORAGE_CLASS_NAME", currentName);
+    stmt.executeNonQuery();
+
+    if(0 == stmt.getNbAffectedRows()) {
+      throw exception::UserError(std::string("Cannot modify storage class ") + instanceName + ":" + currentName +
+        " because it does not exist");
+    }
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
 //------------------------------------------------------------------------------
 // createTapePool
 //------------------------------------------------------------------------------
diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp
index 4e5a9515b5624061341ec897a6d98e8d14f87445..9a1891a1fea54ed4c0e7af220970dd793876081a 100644
--- a/catalogue/RdbmsCatalogue.hpp
+++ b/catalogue/RdbmsCatalogue.hpp
@@ -236,6 +236,16 @@ public:
   void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) override;
   void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const std::string &comment) override;
 
+  /**
+   * Modifies the name of the specified storage class.
+   *
+   * @param diskInstanceName The name of the disk instance to which the
+   * storage class belongs.
+   * @param currentName The current name of the storage class.
+   * @param newName The new name of the storage class.
+   */
+  void modifyStorageClassName(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &currentName, const std::string &newName) override;
+
   void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) override;
   void deleteTapePool(const std::string &name) override;
   std::list<TapePool> getTapePools() const override;