diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -5,3 +5,6 @@
   <https://download.bitcoinabc.org/0.23.8/>
 
 This release includes the following features and fixes:
+ - Add a new option `-networkactive` to enable all P2P network activity
+   (default 1). To start a node offline, you can provide
+   `-networkactive=0` or `-nonetworkactive`.
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -750,6 +750,10 @@
         "-seednode=<ip>",
         "Connect to a node to retrieve peer addresses, and disconnect",
         ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+    gArgs.AddArg("-networkactive",
+                 "Enable all P2P network activity (default: 1). Can be changed "
+                 "by the setnetworkactive RPC command",
+                 ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
     argsman.AddArg("-timeout=<n>",
                    strprintf("Specify connection timeout in milliseconds "
                              "(minimum: 1, default: %d)",
@@ -2278,7 +2282,8 @@
     assert(!node.connman);
     node.connman = std::make_unique<CConnman>(
         config, GetRand(std::numeric_limits<uint64_t>::max()),
-        GetRand(std::numeric_limits<uint64_t>::max()));
+        GetRand(std::numeric_limits<uint64_t>::max()),
+        gArgs.GetBoolArg("-networkactive", true));
 
     // Make mempool generally available in the node context. For example the
     // connection manager, wallet, or RPC threads, which are all started after
diff --git a/src/net.h b/src/net.h
--- a/src/net.h
+++ b/src/net.h
@@ -236,7 +236,8 @@
         }
     }
 
-    CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1);
+    CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1,
+             bool network_active = true);
     ~CConnman();
 
     bool Start(CScheduler &scheduler, const Options &options);
diff --git a/src/net.cpp b/src/net.cpp
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2522,7 +2522,7 @@
 }
 
 void CConnman::SetNetworkActive(bool active) {
-    LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active);
+    LogPrintf("%s: %s\n", __func__, active);
 
     if (fNetworkActive == active) {
         return;
@@ -2532,12 +2532,14 @@
     uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
 }
 
-CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In)
+CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In,
+                   bool network_active)
     : config(&configIn), nSeed0(nSeed0In), nSeed1(nSeed1In) {
     SetTryNewOutboundPeer(false);
 
     Options connOptions;
     Init(connOptions);
+    SetNetworkActive(network_active);
 }
 
 NodeId CConnman::GetNewNodeId() {
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -127,11 +127,38 @@
             ])
         self.stop_node(0)
 
+    def test_networkactive(self):
+        self.log.info('Test -networkactive option')
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']):
+            self.start_node(0)
+        self.stop_node(0)
+
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']):
+            self.start_node(0, extra_args=['-networkactive'])
+        self.stop_node(0)
+
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']):
+            self.start_node(0, extra_args=['-networkactive=1'])
+        self.stop_node(0)
+
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']):
+            self.start_node(0, extra_args=['-networkactive=0'])
+        self.stop_node(0)
+
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']):
+            self.start_node(0, extra_args=['-nonetworkactive'])
+        self.stop_node(0)
+
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']):
+            self.start_node(0, extra_args=['-nonetworkactive=1'])
+        self.stop_node(0)
+
     def run_test(self):
         self.stop_node(0)
 
         self.test_log_buffer()
         self.test_args_log()
+        self.test_networkactive()
 
         self.test_config_file_parser()
 
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -121,13 +121,15 @@
         assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
         assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2)
 
-        self.nodes[0].setnetworkactive(state=False)
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']):
+            self.nodes[0].setnetworkactive(state=False)
         assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], False)
         # Wait a bit for all sockets to close
         wait_until(lambda: self.nodes[0].getnetworkinfo()[
                    'connections'] == 0, timeout=3)
 
-        self.nodes[0].setnetworkactive(state=True)
+        with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: true\n']):
+            self.nodes[0].setnetworkactive(state=True)
         # Connect nodes both ways.
         connect_nodes(self.nodes[0], self.nodes[1])
         connect_nodes(self.nodes[1], self.nodes[0])