diff --git a/tlbmc/configs/entity_config_json_impl.cc b/tlbmc/configs/entity_config_json_impl.cc
index bd0fcff..e452dc0 100644
--- a/tlbmc/configs/entity_config_json_impl.cc
+++ b/tlbmc/configs/entity_config_json_impl.cc
@@ -30,6 +30,7 @@
 #include "absl/strings/str_join.h"
 #include "absl/strings/str_replace.h"
 #include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
 #include "absl/strings/substitute.h"
 #include "absl/time/time.h"
 #include "absl/types/span.h"
@@ -454,9 +455,101 @@
           RE2::FullMatch(find_fru_field->second, *probe_field));
 }
 
+// Probes if the Ipmi Fru matches and updates the fru table and probed
+// config map.
+absl::Status ProbeFru(nlohmann::json& ipmi_fru_object,
+                      const nlohmann::json& config, absl::string_view name,
+                      FruTable& fru_table, ProbedConfigMap& probed_config_map) {
+  if (!ipmi_fru_object.is_array()) {
+    LOG(INFO) << "IpmiFru field is not an array, converting to array";
+    ipmi_fru_object = nlohmann::json::array({ipmi_fru_object});
+  }
+  for (const auto& ipmi_fru : ipmi_fru_object) {
+    // Get probe fields.
+    const auto* board_product_name =
+        GetValueAsString(ipmi_fru, "BOARD_PRODUCT_NAME");
+    const auto* product_product_name =
+        GetValueAsString(ipmi_fru, "PRODUCT_PRODUCT_NAME");
+    const auto* bus = GetValueAsUint(ipmi_fru, "BUS");
+    const auto* address = GetValueAsUint(ipmi_fru, "ADDRESS");
+    const auto* part_number = GetValueAsString(ipmi_fru, "BOARD_PART_NUMBER");
+    const auto* board_info_am2 = GetValueAsString(ipmi_fru, "BOARD_INFO_AM2");
+    const auto* product_info_am2 =
+        GetValueAsString(ipmi_fru, "PRODUCT_INFO_AM2");
+    if (board_product_name == nullptr && product_product_name == nullptr &&
+        bus == nullptr && address == nullptr && part_number == nullptr &&
+        board_info_am2 == nullptr && product_info_am2 == nullptr) {
+      return absl::InvalidArgumentError(
+          "Invalid config: IpmiFru field is not a valid probe");
+    }
+
+    // Check if the FRU matches the probe.
+    for (const auto& [key, fru] : fru_table.key_to_fru()) {
+      bool i2c_info_matches_or_null = false;
+      if ((bus == nullptr && address == nullptr) ||
+          (bus != nullptr && *bus == fru.i2c_info().bus() &&
+           address != nullptr && *address == fru.i2c_info().address())) {
+        i2c_info_matches_or_null = true;
+      }
+
+      // Check if any of the FRU fields match the probe.
+      bool board_product_name_matches_or_null =
+          CheckProbeFieldMatch(board_product_name, fru, "BOARD_PRODUCT_NAME");
+      bool product_product_name_matches_or_null = CheckProbeFieldMatch(
+          product_product_name, fru, "PRODUCT_PRODUCT_NAME");
+      bool part_number_matches_or_null =
+          CheckProbeFieldMatch(part_number, fru, "BOARD_PART_NUMBER");
+      bool board_info_am2_matches_or_null =
+          CheckProbeFieldMatch(board_info_am2, fru, "BOARD_INFO_AM2");
+      bool product_info_am2_matches_or_null =
+          CheckProbeFieldMatch(product_info_am2, fru, "PRODUCT_INFO_AM2");
+
+      // If the FRU doesn't match the probe, continue to the next FRU.
+      if (!i2c_info_matches_or_null || !board_product_name_matches_or_null ||
+          !product_product_name_matches_or_null ||
+          !part_number_matches_or_null || !board_info_am2_matches_or_null ||
+          !product_info_am2_matches_or_null) {
+        continue;
+      }
+
+      // This condition will check that
+      // 1. Only configs containing in $index can have multiple Fru probe true
+      // 2. A Fru cannot match multiple probes within one config
+      // 3. Multiple configs cannot probe true with the same name
+      if (probed_config_map.contains(name) &&
+          !absl::StrContains(name, "$index")) {
+        return absl::InvalidArgumentError(
+            absl::StrCat("Invalid config: Frus match the same config multiple"
+                         " times but config name does not contain $index : ",
+                         name));
+      }
+      // If we reach here, the FRU matches the probe and is unique.
+      auto& probed_data = probed_config_map[name];
+
+      // If the key is in the format of "bus:address", we will parse the bus
+      // and address and use them to construct the FruKey object. Otherwise,
+      // default to the string representation of the FruKey.
+      probed_data.fru_keys.push_back(FruKey(key));
+      probed_data.config = config;
+      LOG(INFO) << "Matched config: " << name << " with FRU: " << key;
+    }
+    // Sort the found FRU keys for each config.
+    if (auto probed_data_it = probed_config_map.find(name);
+        probed_data_it != probed_config_map.end()) {
+      std::sort(probed_data_it->second.fru_keys.begin(),
+                probed_data_it->second.fru_keys.end());
+    }
+  }
+  return absl::OkStatus();
+}
+
+// Processes probe configs and returns a map of them.
 absl::StatusOr<ProbedConfigMap> ProcessConfigs(
     const std::vector<nlohmann::json>& config_list, FruTable& fru_table) {
   ProbedConfigMap probed_config_map;
+  // Map to store the temporary config map for configs that have FOUND probe.
+  absl::flat_hash_map<std::string, std::vector<ProbedConfigData>>
+      pending_config_name_to_probed_configs;
   for (const auto& config : config_list) {
     absl::StatusOr<nlohmann::json> probe_result =
         GetObject(config, kProbeKeyword);
@@ -468,28 +561,41 @@
     ECCLESIA_ASSIGN_OR_RETURN(std::string name, ParseConfigName(config));
     name = absl::StrReplaceAll(name, {{" ", "_"}});
 
-    const std::string* true_str = probe_result->get_ptr<const std::string*>();
-    bool true_value = true_str != nullptr && *true_str == "TRUE";
-    // Check if the probe is a true value.
-    if (true_value) {
-      if (probed_config_map.contains(name)) {
-        return absl::InvalidArgumentError(
-            absl::StrCat("Invalid config: Multiple configs with TRUE probe have"
-                         " the same name: ",
-                         name));
+    const std::string* probe_str = probe_result->get_ptr<const std::string*>();
+    if (probe_str != nullptr) {
+      std::string_view probe_str_view(*probe_str);
+      if (probe_str_view == "TRUE") {
+        if (probed_config_map.contains(name)) {
+          return absl::InvalidArgumentError(
+              absl::StrCat("Invalid config: Multiple configs with TRUE probe"
+                           " have the same name: ",
+                           name));
+        }
+        auto& probed_data = probed_config_map[name];
+        probed_data.fru_keys.push_back(FruKey(name));
+        probed_data.config = config;
+        Fru entity_object;
+        entity_object.mutable_attributes()->set_key(name);
+        entity_object.mutable_attributes()->set_status(STATUS_READY);
+        fru_table.mutable_key_to_fru()->insert({name, entity_object});
+        continue;
       }
-      auto& probed_data = probed_config_map[name];
-      probed_data.fru_keys.push_back(FruKey(name));
-      probed_data.config = config;
-      Fru entity_object;
-      entity_object.mutable_attributes()->set_key(name);
-      entity_object.mutable_attributes()->set_status(STATUS_READY);
-      fru_table.mutable_key_to_fru()->insert({name, entity_object});
-      continue;
-    }
-    bool skip_value = true_str != nullptr && *true_str == "FALSE";
-    if (skip_value) {
-      continue;
+      if (probe_str_view == "FALSE") {
+        continue;
+      }
+      // Store the config in the temporary map with key as FOUND probe
+      // and handle the config later.
+      if (absl::StartsWith(probe_str_view, "FOUND('") &&
+          absl::EndsWith(probe_str_view, "')")) {
+        absl::string_view found_config_name = absl::StripSuffix(
+            absl::StripPrefix(probe_str_view, "FOUND('"), "')");
+        ProbedConfigData probed_data;
+        probed_data.fru_keys.push_back(FruKey(name));
+        probed_data.config = config;
+        pending_config_name_to_probed_configs[found_config_name].push_back(
+            probed_data);
+        continue;
+      }
     }
     nlohmann::json probe = *probe_result;
     // Perform probe.
@@ -500,85 +606,48 @@
           "Invalid config: IpmiFru field is not a valid probe");
     }
     auto ipmi_fru_object = ipmi_fru_it->get<nlohmann::json>();
-    // Wrap single IpmiFru object in array to simplify logic below.
-    if (!ipmi_fru_object.is_array()) {
-      ipmi_fru_object = nlohmann::json::array({ipmi_fru_object});
+    absl::Status probe_fru_status =
+        ProbeFru(ipmi_fru_object, config, name, fru_table, probed_config_map);
+    if (!probe_fru_status.ok()) {
+      return probe_fru_status;
     }
-    for (const auto& ipmi_fru : ipmi_fru_object) {
-      // Get probe fields.
-      const auto* board_product_name =
-          GetValueAsString(ipmi_fru, "BOARD_PRODUCT_NAME");
-      const auto* product_product_name =
-          GetValueAsString(ipmi_fru, "PRODUCT_PRODUCT_NAME");
-      const auto* bus = GetValueAsUint(ipmi_fru, "BUS");
-      const auto* address = GetValueAsUint(ipmi_fru, "ADDRESS");
-      const auto* part_number = GetValueAsString(ipmi_fru, "BOARD_PART_NUMBER");
-      const auto* board_info_am2 = GetValueAsString(ipmi_fru, "BOARD_INFO_AM2");
-      const auto* product_info_am2 =
-          GetValueAsString(ipmi_fru, "PRODUCT_INFO_AM2");
-      if (board_product_name == nullptr && product_product_name == nullptr &&
-          bus == nullptr && address == nullptr && part_number == nullptr &&
-          board_info_am2 == nullptr && product_info_am2 == nullptr) {
-        return absl::InvalidArgumentError(
-            "Invalid config: IpmiFru field is not a valid probe");
-      }
+  }
 
-      // Check if the FRU matches the probe.
-      for (const auto& [key, fru] : fru_table.key_to_fru()) {
-        bool i2c_info_matches_or_null = false;
-        if ((bus == nullptr && address == nullptr) ||
-            (bus != nullptr && *bus == fru.i2c_info().bus() &&
-             address != nullptr && *address == fru.i2c_info().address())) {
-          i2c_info_matches_or_null = true;
-        }
-
-        // Check if any of the FRU fields match the probe.
-        bool board_product_name_matches_or_null =
-            CheckProbeFieldMatch(board_product_name, fru, "BOARD_PRODUCT_NAME");
-        bool product_product_name_matches_or_null = CheckProbeFieldMatch(
-            product_product_name, fru, "PRODUCT_PRODUCT_NAME");
-        bool part_number_matches_or_null =
-            CheckProbeFieldMatch(part_number, fru, "BOARD_PART_NUMBER");
-        bool board_info_am2_matches_or_null =
-            CheckProbeFieldMatch(board_info_am2, fru, "BOARD_INFO_AM2");
-        bool product_info_am2_matches_or_null =
-            CheckProbeFieldMatch(product_info_am2, fru, "PRODUCT_INFO_AM2");
-
-        // If the FRU doesn't match the probe, continue to the next FRU.
-        if (!i2c_info_matches_or_null || !board_product_name_matches_or_null ||
-            !product_product_name_matches_or_null ||
-            !part_number_matches_or_null || !board_info_am2_matches_or_null ||
-            !product_info_am2_matches_or_null) {
-          continue;
-        }
-
-        // This condition will check that
-        // 1. Only configs containing in $index can have multiple Fru probe true
-        // 2. A Fru cannot match multiple probes within one config
-        // 3. Multiple configs cannot probe true with the same name
-        if (probed_config_map.contains(name) &&
+  // Post-process the configs with FOUND probe.
+  // Using topological sort (bfs) to find all the configs which FOUND probe
+  // rule is fulfilled. This is to avoid the recursion approach in
+  // https://github.com/openbmc/entity-manager/blob/7f51d32fb69f3bb6c4eabf685a27b57f345445cb/src/entity_manager/perform_scan.cpp#L582
+  std::queue<std::string> found_target_candidates;
+  for (const auto& [name, _] : probed_config_map) {
+    if (pending_config_name_to_probed_configs.find(name) !=
+        pending_config_name_to_probed_configs.end()) {
+      found_target_candidates.push(name);
+    }
+  }
+  while (!found_target_candidates.empty()) {
+    const std::string name = found_target_candidates.front();
+    found_target_candidates.pop();
+    auto found_config_it = pending_config_name_to_probed_configs.find(name);
+    if (found_config_it != pending_config_name_to_probed_configs.end()) {
+      for (const auto& found_config_data : found_config_it->second) {
+        const std::string config_name =
+            found_config_data.fru_keys[0].ToString();
+        if (probed_config_map.contains(config_name) &&
             !absl::StrContains(name, "$index")) {
           return absl::InvalidArgumentError(
-              absl::StrCat("Invalid config: Frus match the same config multiple"
-                           " times but config name does not contain $index : ",
-                           name));
+              absl::StrCat("Invalid config: Multiple configs with FOUND probe"
+                           " have the same name: ",
+                           config_name));
         }
-        // If we reach here, the FRU matches the probe and is unique.
-        auto& probed_data = probed_config_map[name];
-
-        // If the key is in the format of "bus:address", we will parse the bus
-        // and address and use them to construct the FruKey object. Otherwise,
-        // default to the string representation of the FruKey.
-        probed_data.fru_keys.push_back(FruKey(key));
-        probed_data.config = config;
-        LOG(INFO) << "Matched config: " << name << " with FRU: " << key;
+        found_target_candidates.push(config_name);
+        probed_config_map[config_name] = found_config_data;
+        Fru entity_object;
+        entity_object.mutable_attributes()->set_key(config_name);
+        entity_object.mutable_attributes()->set_status(STATUS_READY);
+        fru_table.mutable_key_to_fru()->insert({config_name, entity_object});
+        LOG(INFO) << "FOUND " << name << ", appending config " << config_name;
       }
-      // Sort the found FRU keys for each config.
-      if (auto probed_data_it = probed_config_map.find(name);
-          probed_data_it != probed_config_map.end()) {
-        std::sort(probed_data_it->second.fru_keys.begin(),
-                  probed_data_it->second.fru_keys.end());
-      }
+      pending_config_name_to_probed_configs.erase(found_config_it);
     }
   }
   return probed_config_map;
