diff --git a/src/upnp/protocol/pupnp/pupnp.cpp b/src/upnp/protocol/pupnp/pupnp.cpp
index 2be07ee59da7e51e921ad27b351d9bd07426b63d..2bedf3ad26ead03b47c437cd5a3be372fc32045b 100644
--- a/src/upnp/protocol/pupnp/pupnp.cpp
+++ b/src/upnp/protocol/pupnp/pupnp.cpp
@@ -167,8 +167,9 @@ PUPnP::~PUPnP()
     {
         std::lock_guard<std::mutex> lock(validIgdListMutex_);
         std::lock_guard<std::mutex> lk(ctrlptMutex_);
-        for (auto const& it : validIgdList_) {
-            removeAllLocalMappings(it);
+        for (auto const& igd : validIgdList_) {
+            if (igd->isValid())
+                deleteMappingsByDescription(igd, Mapping::UPNP_MAPPING_DESCRIPTION_PREFIX);
         }
         validIgdList_.clear();
         clientRegistered_ = false;
@@ -423,8 +424,8 @@ PUPnP::validateIgd(const IGDInfo& info)
         validIgdList_.emplace_back(igd_candidate);
     }
 
-    // Clear existing mappings
-    removeAllLocalMappings(igd_candidate);
+    // Clear mappings from previous instances.
+    deleteMappingsByDescription(igd_candidate, Mapping::UPNP_MAPPING_DESCRIPTION_PREFIX);
 
     // Report to the listener.
     observer_->onIgdUpdated(igd_candidate, UpnpIgdEvent::ADDED);
@@ -601,13 +602,6 @@ PUPnP::requestMappingRemove(const Mapping& igdMapping)
     }
 }
 
-void
-PUPnP::removeAllLocalMappings(const std::shared_ptr<IGD>& igd)
-{
-    if (auto upnpIgd = std::dynamic_pointer_cast<UPnPIGD>(igd))
-        actionDeletePortMappingsByDesc(*upnpIgd, Mapping::UPNP_MAPPING_DESCRIPTION_PREFIX);
-}
-
 const char*
 PUPnP::eventTypeToString(Upnp_EventType eventType)
 {
@@ -1280,92 +1274,21 @@ PUPnP::getMappingsListByDescr(const std::shared_ptr<IGD>& igd, const std::string
     return mapList;
 }
 
-// TODO. Rewrite using getMappingsListByDescr.
 void
-PUPnP::actionDeletePortMappingsByDesc(const UPnPIGD& igd, const std::string& description)
+PUPnP::deleteMappingsByDescription(const std::shared_ptr<IGD>& igd, const std::string& description)
 {
-    if (not(clientRegistered_ and igd.getLocalIp()))
+    if (not(clientRegistered_ and igd->getLocalIp()))
         return;
 
-    // Set action name.
-    static constexpr const char* action_name {"GetGenericPortMappingEntry"};
-    int entry_idx = 0;
-    bool done = false;
+    JAMI_DBG("PUPnP: Remove all mappings (if any) on IGD %s matching descr prefix %s",
+             igd->getLocalIp().toString().c_str(),
+             Mapping::UPNP_MAPPING_DESCRIPTION_PREFIX);
 
-    do {
-        // Action and response pointers.
-        std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&>
-            action(nullptr, ixmlDocument_free); // Action pointer.
-        std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&>
-            response(nullptr, ixmlDocument_free); // Response pointer.
-        IXML_Document* action_container_ptr = nullptr;
-        IXML_Document* response_container_ptr = nullptr;
-
-        UpnpAddToAction(&action_container_ptr,
-                        action_name,
-                        igd.getServiceType().c_str(),
-                        "NewPortMappingIndex",
-                        std::to_string(entry_idx).c_str());
-        action.reset(action_container_ptr);
-
-        int upnp_err = UpnpSendAction(ctrlptHandle_,
-                                      igd.getControlURL().c_str(),
-                                      igd.getServiceType().c_str(),
-                                      nullptr,
-                                      action.get(),
-                                      &response_container_ptr);
-        response.reset(response_container_ptr);
-        if (not response and upnp_err != UPNP_E_SUCCESS) {
-            JAMI_ERR("PUPnP: GetGenericPortMappingEntry did not return a response");
-            return;
-        }
+    auto mapList = getMappingsListByDescr(igd, Mapping::UPNP_MAPPING_DESCRIPTION_PREFIX);
 
-        // Check error code.
-        std::string errorCode = getFirstDocItem(response.get(), "errorCode");
-        if (not errorCode.empty()) {
-            if (std::stoi(errorCode) == ARRAY_IDX_INVALID
-                or std::stoi(errorCode) == CONFLICT_IN_MAPPING) {
-                // No more port mapping entries to delete.
-                JAMI_DBG("PUPnP: Closed all local port mappings");
-            } else {
-                std::string errorDescription = getFirstDocItem(response.get(), "errorDescription");
-                JAMI_DBG("PUPnP: GetGenericPortMappingEntry returned with error: %s: %s",
-                         errorCode.c_str(),
-                         errorDescription.c_str());
-            }
-            done = true;
-        } else {
-            // Parse the rest of the response.
-            std::string desc_actual = getFirstDocItem(response.get(), "NewPortMappingDescription");
-            std::string client_ip = getFirstDocItem(response.get(), "NewInternalClient");
-
-            // Check IP and description.
-            if (client_ip == getUserLocalIp().toString()
-                and desc_actual.find(description) != std::string::npos) {
-                // Get parameters needed for port removal.
-                std::string port_internal = getFirstDocItem(response.get(), "NewInternalPort");
-                std::string port_external = getFirstDocItem(response.get(), "NewExternalPort");
-                std::string protocol = getFirstDocItem(response.get(), "NewProtocol");
-
-                JAMI_DBG("PUPnP: Try remove mapping from previous JAMI instances: [%s] on %s",
-                         desc_actual.c_str(),
-                         igd.getLocalIp().toString().c_str());
-
-                // Attempt to delete entry.
-                if (not actionDeletePortMapping(igd, port_external, protocol)) {
-                    // Failed to delete entry, skip it and try the next one.
-                    JAMI_WARN("PUPnP: Failed to remove mapping [%s] on %s",
-                              desc_actual.c_str(),
-                              igd.getLocalIp().toString().c_str());
-                    ++entry_idx;
-                }
-                // No need to increment index if successful since the number of entries will have
-                // decreased by one.
-            } else {
-                ++entry_idx;
-            }
-        }
-    } while (not done);
+    for (auto const& [_, map] : mapList) {
+        requestMappingRemove(map);
+    }
 }
 
 bool
diff --git a/src/upnp/protocol/pupnp/pupnp.h b/src/upnp/protocol/pupnp/pupnp.h
index 648b15f138e68dd54827693d78047fa3f1871047..b431b01c03a3c89468682ee81582d01673f736d1 100644
--- a/src/upnp/protocol/pupnp/pupnp.h
+++ b/src/upnp/protocol/pupnp/pupnp.h
@@ -139,6 +139,11 @@ public:
     void requestMappingRemove(const Mapping& igdMapping) override;
 
 private:
+
+    // Delete mappings matching the description
+    void deleteMappingsByDescription(const std::shared_ptr<IGD>& igd,
+                                     const std::string& description);
+
     // Process the reception of an add mapping action answer.
     void processAddMapAction(const std::string& ctrlURL,
                              uint16_t ePort,
@@ -154,9 +159,6 @@ private:
     // Returns control point action callback based on xml node.
     CtrlAction getAction(const char* xmlNode);
 
-    // Removes all local mappings of IGD that we're added by the application.
-    void removeAllLocalMappings(const std::shared_ptr<IGD>& igd);
-
     // Validate IGD from the xml document received from the router.
     bool validateIgd(const IGDInfo&);
 
@@ -198,8 +200,6 @@ private:
     bool actionIsIgdConnected(const UPnPIGD& igd);
     IpAddr actionGetExternalIP(const UPnPIGD& igd);
 
-    void actionDeletePortMappingsByDesc(const UPnPIGD& igd, const std::string& description);
-
     bool actionDeletePortMapping(const UPnPIGD& igd,
                                  const std::string& port_external,
                                  const std::string& protocol);