diff --git a/src/dht.cpp b/src/dht.cpp
index 02b3357318ece9ce80667ce8dd837f039e482ca1..39a5df0807632ebd842e6f05ee7414e528661a28 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -574,11 +574,10 @@ Dht::Search::insertNode(std::shared_ptr<Node> node, time_point now, const Blob&
     const auto& nid = node->id;
 
     // Fast track for the case where the node is not relevant for this search
-    if (node->isExpired() && nodes.size() >= SEARCH_NODES && id.xorCmp(nid, nodes.back().node->id) > 0)
+    if (nodes.size() >= SEARCH_NODES && id.xorCmp(nid, nodes.back().node->id) > 0)
         return false;
 
     bool found = false;
-    unsigned num_bad_nodes = getNumberOfBadNodes();
     auto n = std::find_if(nodes.begin(), nodes.end(), [&](const SearchNode& sn) {
         if (sn.node == node) {
             found = true;
@@ -589,15 +588,13 @@ Dht::Search::insertNode(std::shared_ptr<Node> node, time_point now, const Blob&
 
     bool new_search_node = false;
     if (!found) {
-        // Be more restricitve if there are too many
-        // good or unknown nodes in this search,
-        if (nodes.size() - num_bad_nodes - current_get_requests >= SEARCH_NODES) {
-            if (node->isExpired() or n == nodes.end())
-                return false;
-        }
+        // Be more restricitve if there are
+        // too many nodes in this search,
+        if (nodes.size() >= SEARCH_NODES && n == nodes.end())
+            return false;
 
         // Reset search timer if the search is empty
-        if (nodes.empty()) {
+        else if (nodes.empty()) {
             step_time = TIME_INVALID;
             current_get_requests = 0;
         }
@@ -606,17 +603,14 @@ Dht::Search::insertNode(std::shared_ptr<Node> node, time_point now, const Blob&
         node->time = now;
         new_search_node = true;
 
-        // trim good nodes
-        while (nodes.size()-num_bad_nodes-current_get_requests > SEARCH_NODES) {
-            if (removeExpiredNode(now))
-                num_bad_nodes--;
-
-            auto to_remove = std::find_if(nodes.rbegin(), nodes.rend(),
-                [&](const SearchNode& n) { return not (n.isBad() or (n.getStatus and n.getStatus->pending())); }
-            );
-            if (to_remove != nodes.rend()) {
-                nodes.erase(std::prev(to_remove.base()));
-            } // else, all nodes are expired.
+        // trim nodes
+        while (nodes.size() > SEARCH_NODES) {
+            auto to_remove = std::prev(nodes.end());
+            if (to_remove->getStatus and to_remove->getStatus->pending()) {
+                to_remove->getStatus->cancel();
+                current_get_requests--;
+            }
+            nodes.erase(to_remove);
         }
         expired = false;
     }
@@ -850,47 +844,47 @@ Dht::searchStep(std::shared_ptr<Search> sr)
         }
         if (sr->callbacks.empty() && sr->announce.empty() && sr->listeners.empty())
             sr->done = true;
-    }
-
-    if (sr->current_get_requests < SEARCH_REQUESTS) {
-        unsigned i = 0;
-        SearchNode* sent;
-        do {
-            sent = searchSendGetValues(sr);
-            if (sent and not sent->candidate)
-                i++;
-        }
-        while (sent and sr->current_get_requests < SEARCH_REQUESTS);
-        DHT_LOG.DEBUG("[search %s IPv%c] step: sent %u requests (total %u).",
-            sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', i, sr->current_get_requests);
-
-        auto expiredn = (size_t)std::count_if(sr->nodes.begin(), sr->nodes.end(), [&](const SearchNode& sn) {
-                    return sn.candidate or sn.node->isExpired();
-                });
-        if (i == 0 && expiredn == sr->nodes.size())
-        {
-            DHT_LOG.ERROR("[search %s IPv%c] expired", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6');
-            // no nodes or all expired nodes
-            sr->expired = true;
-            if (sr->announce.empty() && sr->listeners.empty()) {
-                // Listening or announcing requires keeping the cluster up to date.
-                sr->done = true;
+    } else {
+        if (sr->current_get_requests < SEARCH_REQUESTS) {
+            unsigned i = 0;
+            SearchNode* sent;
+            do {
+                sent = searchSendGetValues(sr);
+                if (sent and not sent->candidate)
+                    i++;
             }
+            while (sent and sr->current_get_requests < SEARCH_REQUESTS);
+            DHT_LOG.DEBUG("[search %s IPv%c] step: sent %u requests (total %u).",
+                sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', i, sr->current_get_requests);
+
+            auto expiredn = (size_t)std::count_if(sr->nodes.begin(), sr->nodes.end(), [&](const SearchNode& sn) {
+                        return sn.candidate or sn.node->isExpired();
+                    });
+            if (i == 0 && expiredn == sr->nodes.size())
             {
-                auto get_cbs = std::move(sr->callbacks);
-                for (const auto& g : get_cbs) {
-                    if (g.done_cb)
-                        g.done_cb(false, {});
+                DHT_LOG.ERROR("[search %s IPv%c] expired", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6');
+                // no nodes or all expired nodes
+                sr->expired = true;
+                if (sr->announce.empty() && sr->listeners.empty()) {
+                    // Listening or announcing requires keeping the cluster up to date.
+                    sr->done = true;
+                }
+                {
+                    auto get_cbs = std::move(sr->callbacks);
+                    for (const auto& g : get_cbs) {
+                        if (g.done_cb)
+                            g.done_cb(false, {});
+                    }
+                }
+                {
+                    std::vector<DoneCallback> a_cbs;
+                    a_cbs.reserve(sr->announce.size());
+                    for (const auto& a : sr->announce)
+                        if (a.callback)
+                            a_cbs.emplace_back(std::move(a.callback));
+                    for (const auto& a : a_cbs)
+                        a(false, {});
                 }
-            }
-            {
-                std::vector<DoneCallback> a_cbs;
-                a_cbs.reserve(sr->announce.size());
-                for (const auto& a : sr->announce)
-                    if (a.callback)
-                        a_cbs.emplace_back(std::move(a.callback));
-                for (const auto& a : a_cbs)
-                    a(false, {});
             }
         }
     }