diff --git a/src/avalanche/proof.cpp b/src/avalanche/proof.cpp
--- a/src/avalanche/proof.cpp
+++ b/src/avalanche/proof.cpp
@@ -108,6 +108,14 @@
                            });
 }
 
+static bool IsStandardPayoutScript(const CScript &scriptPubKey) {
+    // Check the script's standardness against the default max OP_RETURN size,
+    // so that a proof's validity is not affected by a local relay policy
+    // parameter (see -datacarriersize config option)
+    TxoutType scriptType;
+    return IsStandard(scriptPubKey, MAX_OP_RETURN_RELAY, scriptType);
+}
+
 bool Proof::verify(const Amount &stakeUtxoDustThreshold,
                    ProofValidationState &state) const {
     if (stakes.empty()) {
@@ -120,8 +128,7 @@
             strprintf("%u > %u", stakes.size(), AVALANCHE_MAX_PROOF_STAKES));
     }
 
-    TxoutType scriptType;
-    if (!IsStandard(payoutScriptPubKey, scriptType)) {
+    if (!IsStandardPayoutScript(payoutScriptPubKey)) {
         return state.Invalid(ProofValidationResult::INVALID_PAYOUT_SCRIPT,
                              "payout-script-non-standard");
     }
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1970,9 +1970,6 @@
         return false;
     }
 
-    fAcceptDatacarrier =
-        args.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER);
-
     // Option to startup with mocktime set (used for regression testing):
     SetMockTime(args.GetIntArg("-mocktime", 0)); // SetMockTime(0) is a no-op
 
diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h
--- a/src/kernel/mempool_options.h
+++ b/src/kernel/mempool_options.h
@@ -5,6 +5,7 @@
 #define BITCOIN_KERNEL_MEMPOOL_OPTIONS_H
 
 #include <policy/policy.h>
+#include <script/standard.h>
 
 #include <chrono>
 #include <cstdint>
@@ -35,6 +36,17 @@
      * mining and transaction creation)
      */
     CFeeRate min_relay_feerate{DEFAULT_MIN_RELAY_TX_FEE_PER_KB};
+    /**
+     * A data carrying output is an unspendable output containing data. The
+     * script type is designated as TxoutType::NULL_DATA.
+     *
+     * Maximum size of TxoutType::NULL_DATA scripts that this node considers
+     * standard.
+     * If nullopt, any size is nonstandard.
+     */
+    std::optional<unsigned> max_datacarrier_bytes{
+        DEFAULT_ACCEPT_DATACARRIER ? std::optional{MAX_OP_RETURN_RELAY}
+                                   : std::nullopt};
     bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
     bool require_standard{true};
 };
diff --git a/src/mempool_args.cpp b/src/mempool_args.cpp
--- a/src/mempool_args.cpp
+++ b/src/mempool_args.cpp
@@ -48,6 +48,12 @@
     mempool_opts.permit_bare_multisig =
         argsman.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
 
+    mempool_opts.max_datacarrier_bytes =
+        argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)
+            ? std::optional<unsigned>{argsman.GetIntArg("-datacarriersize",
+                                                        MAX_OP_RETURN_RELAY)}
+            : std::nullopt;
+
     mempool_opts.require_standard =
         !argsman.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
     if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {
diff --git a/src/policy/policy.h b/src/policy/policy.h
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -10,6 +10,7 @@
 #include <feerate.h>
 #include <script/standard.h>
 
+#include <optional>
 #include <string>
 
 class CCoinsViewCache;
@@ -111,15 +112,19 @@
 
 bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFee);
 
-bool IsStandard(const CScript &scriptPubKey, TxoutType &whichType);
+bool IsStandard(const CScript &scriptPubKey,
+                const std::optional<unsigned> &max_datacarrier_bytes,
+                TxoutType &whichType);
 
 /**
  * Check for standard transaction types
  * @return True if all outputs (scriptPubKeys) use only standard transaction
  * forms
  */
-bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig,
-                  const CFeeRate &dust_relay_fee, std::string &reason);
+bool IsStandardTx(const CTransaction &tx,
+                  const std::optional<unsigned> &max_datacarrier_bytes,
+                  bool permit_bare_multisig, const CFeeRate &dust_relay_fee,
+                  std::string &reason);
 
 /**
  * Check for standard transaction types
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -35,7 +35,9 @@
     return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
 }
 
-bool IsStandard(const CScript &scriptPubKey, TxoutType &whichType) {
+bool IsStandard(const CScript &scriptPubKey,
+                const std::optional<unsigned> &max_datacarrier_bytes,
+                TxoutType &whichType) {
     std::vector<std::vector<uint8_t>> vSolutions;
     whichType = Solver(scriptPubKey, vSolutions);
 
@@ -52,13 +54,8 @@
             return false;
         }
     } else if (whichType == TxoutType::NULL_DATA) {
-        if (!fAcceptDatacarrier) {
-            return false;
-        }
-
-        unsigned nMaxDatacarrierBytes =
-            gArgs.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
-        if (scriptPubKey.size() > nMaxDatacarrierBytes) {
+        if (!max_datacarrier_bytes ||
+            scriptPubKey.size() > *max_datacarrier_bytes) {
             return false;
         }
     }
@@ -66,8 +63,10 @@
     return true;
 }
 
-bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig,
-                  const CFeeRate &dust_relay_fee, std::string &reason) {
+bool IsStandardTx(const CTransaction &tx,
+                  const std::optional<unsigned> &max_datacarrier_bytes,
+                  bool permit_bare_multisig, const CFeeRate &dust_relay_fee,
+                  std::string &reason) {
     // Only allow these tx versions, there is no point accepting a tx that
     // violates the consensus rules
     if (tx.nVersion > CTransaction::MAX_VERSION ||
@@ -100,7 +99,8 @@
     unsigned int nDataOut = 0;
     TxoutType whichType;
     for (const CTxOut &txout : tx.vout) {
-        if (!::IsStandard(txout.scriptPubKey, whichType)) {
+        if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes,
+                          whichType)) {
             reason = "scriptpubkey";
             return false;
         }
diff --git a/src/script/standard.h b/src/script/standard.h
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -35,12 +35,6 @@
  */
 static const unsigned int MAX_OP_RETURN_RELAY = 223;
 
-/**
- * A data carrying output is an unspendable output containing data. The script
- * type is designated as TxoutType::NULL_DATA.
- */
-extern bool fAcceptDatacarrier;
-
 enum class TxoutType {
     NONSTANDARD,
     // 'standard' transaction types:
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -11,8 +11,6 @@
 
 typedef std::vector<uint8_t> valtype;
 
-bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
-
 CScriptID::CScriptID(const CScript &in) : BaseHash(Hash160(in)) {}
 CScriptID::CScriptID(const ScriptHash &in)
     : BaseHash(static_cast<uint160>(in)) {}
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp
--- a/src/test/fuzz/key.cpp
+++ b/src/test/fuzz/key.cpp
@@ -157,13 +157,13 @@
 
         TxoutType which_type_tx_pubkey;
         const bool is_standard_tx_pubkey =
-            IsStandard(tx_pubkey_script, which_type_tx_pubkey);
+            IsStandard(tx_pubkey_script, std::nullopt, which_type_tx_pubkey);
         assert(is_standard_tx_pubkey);
         assert(which_type_tx_pubkey == TxoutType::PUBKEY);
 
         TxoutType which_type_tx_multisig;
-        const bool is_standard_tx_multisig =
-            IsStandard(tx_multisig_script, which_type_tx_multisig);
+        const bool is_standard_tx_multisig = IsStandard(
+            tx_multisig_script, std::nullopt, which_type_tx_multisig);
         assert(is_standard_tx_multisig);
         assert(which_type_tx_multisig == TxoutType::MULTISIG);
 
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -72,7 +72,9 @@
     (void)IsSolvable(signing_provider, script);
 
     TxoutType which_type;
-    (void)IsStandard(script, which_type);
+    (void)IsStandard(script, std::nullopt, which_type);
+    (void)IsStandard(script, fuzzed_data_provider.ConsumeIntegral<unsigned>(),
+                     which_type);
 
     (void)RecursiveDynamicUsage(script);
 
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -64,10 +64,12 @@
 
     const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE};
     std::string reason;
-    const bool is_standard_with_permit_bare_multisig = IsStandardTx(
-        tx, /* permit_bare_multisig= */ true, dust_relay_fee, reason);
-    const bool is_standard_without_permit_bare_multisig = IsStandardTx(
-        tx, /* permit_bare_multisig= */ false, dust_relay_fee, reason);
+    const bool is_standard_with_permit_bare_multisig =
+        IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ true,
+                     dust_relay_fee, reason);
+    const bool is_standard_without_permit_bare_multisig =
+        IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ false,
+                     dust_relay_fee, reason);
     if (is_standard_without_permit_bare_multisig) {
         assert(is_standard_with_permit_bare_multisig);
     }
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -174,30 +174,37 @@
         key[i].MakeNewKey(true);
     }
 
-    TxoutType whichType;
+    const auto is_standard{[](const CScript &spk) {
+        TxoutType type;
+        bool res{::IsStandard(spk, std::nullopt, type)};
+        if (res) {
+            BOOST_CHECK_EQUAL(type, TxoutType::MULTISIG);
+        }
+        return res;
+    }};
 
     CScript a_and_b;
     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey())
             << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
-    BOOST_CHECK(::IsStandard(a_and_b, whichType));
+    BOOST_CHECK(is_standard(a_and_b));
 
     CScript a_or_b;
     a_or_b << OP_1 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
-    BOOST_CHECK(::IsStandard(a_or_b, whichType));
+    BOOST_CHECK(is_standard(a_or_b));
 
     CScript escrow;
     escrow << OP_2 << ToByteVector(key[0].GetPubKey())
            << ToByteVector(key[1].GetPubKey())
            << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
-    BOOST_CHECK(::IsStandard(escrow, whichType));
+    BOOST_CHECK(is_standard(escrow));
 
     CScript one_of_four;
     one_of_four << OP_1 << ToByteVector(key[0].GetPubKey())
                 << ToByteVector(key[1].GetPubKey())
                 << ToByteVector(key[2].GetPubKey())
                 << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
-    BOOST_CHECK(!::IsStandard(one_of_four, whichType));
+    BOOST_CHECK(!is_standard(one_of_four));
 
     CScript malformed[6];
     malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey())
@@ -218,7 +225,7 @@
                  << ToByteVector(key[1].GetPubKey());
 
     for (int i = 0; i < 6; i++) {
-        BOOST_CHECK(!::IsStandard(malformed[i], whichType));
+        BOOST_CHECK(!is_standard(malformed[i]));
     }
 }
 
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -21,7 +21,7 @@
 
 // Helpers:
 static bool IsStandardTx(const CTransaction &tx, std::string &reason) {
-    return IsStandardTx(tx, DEFAULT_PERMIT_BAREMULTISIG,
+    return IsStandardTx(tx, std::nullopt, DEFAULT_PERMIT_BAREMULTISIG,
                         CFeeRate{DUST_RELAY_TX_FEE}, reason);
 }
 
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -605,7 +605,8 @@
     t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
 
     std::string reason;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // Check dust with default relay fee:
     Amount nDustThreshold = 3 * 182 * g_dust.GetFeePerK() / 1000;
@@ -613,34 +614,41 @@
     // dust:
     t.vout[0].nValue = nDustThreshold - SATOSHI;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "dust");
     // not dust:
     t.vout[0].nValue = nDustThreshold;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // Disallowed nVersion
     t.nVersion = -1;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     t.nVersion = 0;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     t.nVersion = 3;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     // Allowed nVersion
     t.nVersion = 1;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     t.nVersion = 2;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // Check dust with odd relay fee to verify rounding:
     // nDustThreshold = 182 * 1234 / 1000 * 3
@@ -648,16 +656,19 @@
     // dust:
     t.vout[0].nValue = (672 - 1) * SATOSHI;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "dust");
     // not dust:
     t.vout[0].nValue = 672 * SATOSHI;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
     g_dust = CFeeRate{DUST_RELAY_TX_FEE};
 
     t.vout[0].scriptPubKey = CScript() << OP_1;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
@@ -674,7 +685,8 @@
                               "f5d00d4adf73f2dd112ca75cf19754651909becfbe65aed1"
                               "3afb2ab8");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
     t.vout[0].scriptPubKey =
@@ -691,14 +703,14 @@
                               "3afb2ab800");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     /**
-     * Check when a custom value is used for -datacarriersize .
+     * Check when a custom value is used for max_datacarrier_bytes.
      */
     unsigned newMaxSize = 90;
-    gArgs.ForceSetArg("-datacarriersize", ToString(newMaxSize));
 
     // Max user provided payload size is standard
     t.vout[0].scriptPubKey =
@@ -708,7 +720,8 @@
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef3877696e64657878");
     BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize);
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, newMaxSize, g_bare_multi, g_dust,
+                             reason));
 
     // Max user provided payload size + 1 is non-standard
     t.vout[0].scriptPubKey =
@@ -718,39 +731,43 @@
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef3877696e6465787800");
     BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize + 1);
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
-
-    // Clear custom confirguration.
-    gArgs.ClearForcedArg("-datacarriersize");
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, newMaxSize, g_bare_multi, g_dust,
+                              reason));
 
     // Data payload can be encoded in any way...
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
     t.vout[0].scriptPubKey = CScript()
                              << OP_RETURN << ParseHex("00") << ParseHex("01");
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
     // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0
                                        << ParseHex("01") << 2 << 3 << 4 << 5
                                        << 6 << 7 << 8 << 9 << 10 << 11 << 12
                                        << 13 << 14 << 15 << 16;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
     t.vout[0].scriptPubKey = CScript()
                              << OP_RETURN << 0 << ParseHex("01") << 2
                              << ParseHex("fffffffffffffffffffffffffffffffffffff"
                                          "fffffffffffffffffffffffffffffffffff");
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // ...so long as it only contains PUSHDATA's
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     // TxoutType::NULL_DATA w/o PUSHDATA
     t.vout.resize(1);
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     // Only one TxoutType::NULL_DATA permitted in all cases
     t.vout.resize(2);
@@ -763,7 +780,8 @@
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     t.vout[0].scriptPubKey =
@@ -772,13 +790,15 @@
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     // Check large scriptSig (non-standard if size is >1650 bytes)
@@ -787,11 +807,13 @@
     t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
     // OP_PUSHDATA2 with len (3 bytes) + data (1647 bytes) = 1650 bytes
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1647, 0); // 1650
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1648, 0); // 1651
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "scriptsig-size");
 
     // Check scriptSig format (non-standard if there are any other ops than just
@@ -806,7 +828,8 @@
                          << std::vector<uint8_t>(235, 0)
                          // OP_PUSHDATA2 x [...x bytes...]
                          << std::vector<uint8_t>(1234, 0) << OP_9;
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     const std::vector<uint8_t> non_push_ops = {
         // arbitrary set of non-push operations
@@ -842,14 +865,14 @@
         // replace current push-op with each non-push-op
         for (auto op : non_push_ops) {
             t.vin[0].scriptSig[index] = op;
-            BOOST_CHECK(
-                !IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+            BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                                      g_bare_multi, g_dust, reason));
             BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
         }
         // restore op
         t.vin[0].scriptSig[index] = orig_op;
-        BOOST_CHECK(
-            IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+        BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                                 g_bare_multi, g_dust, reason));
     }
 
     // Check bare multisig (standard if policy flag g_bare_multi is set)
@@ -857,11 +880,13 @@
     // simple 1-of-1
     t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()});
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(65, 0);
-    BOOST_CHECK(IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi,
+                             g_dust, reason));
 
     g_bare_multi = false;
     reason.clear();
-    BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_bare_multi, g_dust, reason));
+    BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY,
+                              g_bare_multi, g_dust, reason));
     BOOST_CHECK_EQUAL(reason, "bare-multisig");
     g_bare_multi = DEFAULT_PERMIT_BAREMULTISIG;
 }
diff --git a/src/txmempool.h b/src/txmempool.h
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -479,6 +479,7 @@
     const std::chrono::seconds m_expiry;
     const CFeeRate m_min_relay_feerate;
     const bool m_permit_bare_multisig;
+    const std::optional<unsigned> m_max_datacarrier_bytes;
     const bool m_require_standard;
 
     /**
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -162,6 +162,7 @@
     : m_check_ratio(opts.check_ratio), m_max_size_bytes{opts.max_size_bytes},
       m_expiry{opts.expiry}, m_min_relay_feerate{opts.min_relay_feerate},
       m_permit_bare_multisig{opts.permit_bare_multisig},
+      m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
       m_require_standard{opts.require_standard} {
     // lock free clear
     _clear();
diff --git a/src/util/system.cpp b/src/util/system.cpp
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -7,6 +7,7 @@
 
 #include <chainparamsbase.h>
 #include <fs.h>
+#include <script/standard.h>
 #include <sync.h>
 #include <util/getuniquepath.h>
 #include <util/strencodings.h>
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -519,8 +519,8 @@
     // Rather not work on nonstandard transactions (unless -testnet)
     std::string reason;
     if (m_pool.m_require_standard &&
-        !IsStandardTx(tx, m_pool.m_permit_bare_multisig, ::dustRelayFee,
-                      reason)) {
+        !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes,
+                      m_pool.m_permit_bare_multisig, ::dustRelayFee, reason)) {
         return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
     }