diff --git a/src/index/base.cpp b/src/index/base.cpp
index bcfe7215beaf4a..48274791d44c44 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -67,8 +67,8 @@ void BaseIndex::DB::WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator
     batch.Write(DB_BEST_BLOCK, locator);
 }
 
-BaseIndex::BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name)
-    : m_chain{std::move(chain)}, m_name{std::move(name)} {}
+BaseIndex::BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name, int start_height)
+    : m_chain{std::move(chain)}, m_name{std::move(name)}, m_start_height{std::move(start_height)} {}
 
 BaseIndex::~BaseIndex()
 {
@@ -125,11 +125,12 @@ bool BaseIndex::Init()
     return true;
 }
 
-static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain& chain) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain& chain, int start_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
 {
     AssertLockHeld(cs_main);
 
     if (!pindex_prev) {
+        if (start_height > 0) return chain[start_height];
         return chain.Genesis();
     }
 
@@ -161,7 +162,7 @@ void BaseIndex::ThreadSync()
 
             {
                 LOCK(cs_main);
-                const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
+                const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain, m_start_height);
                 if (!pindex_next) {
                     SetBestBlockIndex(pindex);
                     m_synced = true;
diff --git a/src/index/base.h b/src/index/base.h
index 154061fb19120f..359358faaa057a 100644
--- a/src/index/base.h
+++ b/src/index/base.h
@@ -107,6 +107,7 @@ class BaseIndex : public CValidationInterface
     std::unique_ptr<interfaces::Chain> m_chain;
     Chainstate* m_chainstate{nullptr};
     const std::string m_name;
+    const int m_start_height{0};
 
     void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
 
@@ -132,7 +133,7 @@ class BaseIndex : public CValidationInterface
     void SetBestBlockIndex(const CBlockIndex* block);
 
 public:
-    BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name);
+    BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name, int start_height = 0);
     /// Destructor interrupts sync thread if running and blocks until it exits.
     virtual ~BaseIndex();
 
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 58f777b3266073..bc7e68c01c3cd0 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -14,6 +14,7 @@
 #include <undo.h>
 #include <util/fs_helpers.h>
 #include <validation.h>
+#include <chainparams.h>
 
 /* The index database stores three items for each block: the disk location of the encoded filter,
  * its dSHA256 hash, and the header. Those belonging to blocks on the active chain are indexed by
@@ -99,7 +100,11 @@ static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
 
 BlockFilterIndex::BlockFilterIndex(std::unique_ptr<interfaces::Chain> chain, BlockFilterType filter_type,
                                    size_t n_cache_size, bool f_memory, bool f_wipe)
-    : BaseIndex(std::move(chain), BlockFilterTypeName(filter_type) + " block filter index")
+    : BaseIndex(
+            std::move(chain),
+            BlockFilterTypeName(filter_type) + " block filter index",
+            (filter_type == BlockFilterType::SILENT_PAYMENTS ? Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height : 0)
+    )
     , m_filter_type(filter_type)
 {
     const std::string& filter_name = BlockFilterTypeName(filter_type);