diff --git a/src/connectivity/turn_cache.cpp b/src/connectivity/turn_cache.cpp
index 2a6d856f92c6421fecf115af063f0d5312190d0d..12fbb43c3c358139420da84e5253d5b3bac65af0 100644
--- a/src/connectivity/turn_cache.cpp
+++ b/src/connectivity/turn_cache.cpp
@@ -24,6 +24,7 @@
 #include "fileutils.h"
 #include "manager.h"
 #include "opendht/thread_pool.h" // TODO remove asio
+#include "turn_cache.h"
 
 namespace jami {
 
@@ -37,10 +38,25 @@ TurnCache::TurnCache(const std::string& accountId,
 {
     refreshTimer_ = std::make_unique<asio::steady_timer>(*io_context,
                                                          std::chrono::steady_clock::now());
+    onConnectedTimer_ = std::make_unique<asio::steady_timer>(*io_context,
+                                                         std::chrono::steady_clock::now());
     reconfigure(params, enabled);
 }
 
-TurnCache::~TurnCache() {}
+TurnCache::~TurnCache() {
+    {
+        std::lock_guard<std::mutex> lock(shutdownMtx_);
+        onConnectedTimer_->cancel();
+        onConnectedTimer_.reset();
+    }
+    {
+        std::lock_guard<std::mutex> lock(cachedTurnMutex_);
+        testTurnV4_.reset();
+        testTurnV6_.reset();
+        cacheTurnV4_.reset();
+        cacheTurnV6_.reset();
+    }
+}
 
 std::optional<IpAddr>
 TurnCache::getResolvedTurn(uint16_t family) const
@@ -159,24 +175,40 @@ TurnCache::testTurn(IpAddr server)
     try {
         turn = std::make_unique<TurnTransport>(
             params, std::move([this, server](bool ok) {
-                std::lock_guard<std::mutex> lk(cachedTurnMutex_);
-                auto& cacheTurn = server.isIpv4() ? cacheTurnV4_ : cacheTurnV6_;
-                if (!ok) {
-                    JAMI_ERROR("Connection to {:s} failed - reset", server.toString());
-                    cacheTurn.reset();
-                } else {
-                    JAMI_DEBUG("Connection to {:s} ready", server.toString());
-                    cacheTurn = std::make_unique<IpAddr>(server);
+                // Stop server in an async job, because this callback can be called
+                // immediately and cachedTurnMutex_ must not be locked.
+                std::lock_guard<std::mutex> lock(shutdownMtx_);
+                if (onConnectedTimer_) {
+                    onConnectedTimer_->expires_at(std::chrono::steady_clock::now());
+                    onConnectedTimer_->async_wait(std::bind(&TurnCache::onConnected, this, std::placeholders::_1, ok, server));
                 }
-                refreshTurnDelay(!cacheTurnV6_ && !cacheTurnV4_);
-                auto& turn = server.isIpv4() ? testTurnV4_ : testTurnV6_;
-                turn->shutdown();
             }));
     } catch (const std::exception& e) {
         JAMI_ERROR("TurnTransport creation error: {}", e.what());
     }
 }
 
+void
+TurnCache::onConnected(const asio::error_code& ec, bool ok, IpAddr server)
+{
+    if (ec == asio::error::operation_aborted)
+        return;
+
+    std::lock_guard<std::mutex> lk(cachedTurnMutex_);
+    auto& cacheTurn = server.isIpv4() ? cacheTurnV4_ : cacheTurnV6_;
+    if (!ok) {
+        JAMI_ERROR("Connection to {:s} failed - reset", server.toString());
+        cacheTurn.reset();
+    } else {
+        JAMI_DEBUG("Connection to {:s} ready", server.toString());
+        cacheTurn = std::make_unique<IpAddr>(server);
+    }
+    refreshTurnDelay(!cacheTurnV6_ && !cacheTurnV4_);
+    if (auto& turn = server.isIpv4() ? testTurnV4_ : testTurnV6_)
+        turn->shutdown();
+}
+
+
 void
 TurnCache::refreshTurnDelay(bool scheduleNext)
 {
diff --git a/src/connectivity/turn_cache.h b/src/connectivity/turn_cache.h
index 967ede7abb8dabd42318af168889d80912ab10d0..9c5fa04f3ddbd96dba76d994e1067eb540691df2 100644
--- a/src/connectivity/turn_cache.h
+++ b/src/connectivity/turn_cache.h
@@ -80,9 +80,15 @@ private:
     std::unique_ptr<IpAddr> cacheTurnV4_ {};
     std::unique_ptr<IpAddr> cacheTurnV6_ {};
 
+    void onConnected(const asio::error_code& ec, bool ok, IpAddr server);
+
     // io
     std::shared_ptr<asio::io_context> io_context;
     std::unique_ptr<asio::steady_timer> refreshTimer_;
+    std::unique_ptr<asio::steady_timer> onConnectedTimer_;
+
+    std::mutex shutdownMtx_;
+
 };
 
 } // namespace jami