diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -2413,6 +2413,8 @@
         options.check_blocks =
             args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
         options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
+        options.require_full_verification =
+            args.IsArgSet("-checkblocks") || args.IsArgSet("-checklevel");
         options.check_interrupt = ShutdownRequested;
         options.coins_error_cb = [] {
             uiInterface.ThreadSafeMessageBox(
@@ -2452,7 +2454,9 @@
             }
         }
 
-        if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB) {
+        if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB ||
+            status ==
+                node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) {
             return InitError(error);
         }
 
diff --git a/src/node/chainstate.h b/src/node/chainstate.h
--- a/src/node/chainstate.h
+++ b/src/node/chainstate.h
@@ -30,6 +30,7 @@
     bool reindex{false};
     bool reindex_chainstate{false};
     bool prune{false};
+    bool require_full_verification{true};
     int64_t check_blocks{DEFAULT_CHECKBLOCKS};
     int64_t check_level{DEFAULT_CHECKLEVEL};
     std::function<bool()> check_interrupt;
@@ -44,6 +45,7 @@
     SUCCESS,
     FAILURE,
     FAILURE_INCOMPATIBLE_DB,
+    FAILURE_INSUFFICIENT_DBCACHE,
     INTERRUPTED
 };
 
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp
--- a/src/node/chainstate.cpp
+++ b/src/node/chainstate.cpp
@@ -287,6 +287,13 @@
                 case VerifyDBResult::CORRUPTED_BLOCK_DB:
                     return {ChainstateLoadStatus::FAILURE,
                             _("Corrupted block database detected")};
+                case VerifyDBResult::SKIPPED_L3_CHECKS:
+                    if (options.require_full_verification) {
+                        return {
+                            ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE,
+                            _("Insufficient dbcache for block verification")};
+                    }
+                    break;
             } // no default case, so the compiler can warn about missing cases
         }
     }
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1622,7 +1622,9 @@
              RPCArg::DefaultHint{strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS)},
              "The number of blocks to check."},
         },
-        RPCResult{RPCResult::Type::BOOL, "", "Verified or not"},
+        RPCResult{RPCResult::Type::BOOL, "",
+                  "Verification finished successfully. If false, check "
+                  "debug.log for reason."},
         RPCExamples{HelpExampleCli("verifychain", "") +
                     HelpExampleRpc("verifychain", "")},
         [&](const RPCHelpMan &self, const Config &config,
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -221,6 +221,8 @@
     options.check_blocks =
         m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
     options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
+    options.require_full_verification =
+        m_args.IsArgSet("-checkblocks") || m_args.IsArgSet("-checklevel");
     auto [status, error] =
         LoadChainstate(*Assert(m_node.chainman), m_cache_sizes, options);
     assert(status == node::ChainstateLoadStatus::SUCCESS);
diff --git a/src/validation.h b/src/validation.h
--- a/src/validation.h
+++ b/src/validation.h
@@ -566,6 +566,7 @@
     SUCCESS,
     CORRUPTED_BLOCK_DB,
     INTERRUPTED,
+    SKIPPED_L3_CHECKS,
 };
 
 /**
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -4784,6 +4784,9 @@
               "blocks (%i transactions)\n",
               block_count, nGoodTransactions);
 
+    if (skipped_l3_checks) {
+        return VerifyDBResult::SKIPPED_L3_CHECKS;
+    }
     return VerifyDBResult::SUCCESS;
 }