diff --git a/zebra/main.c b/zebra/main.c
index 4d9b7c3bbe35..138a955bc313 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -54,6 +54,8 @@
 
 #define ZEBRA_PTM_SUPPORT
 
+char *zserv_path;
+
 /* process id. */
 pid_t pid;
 
@@ -314,17 +316,46 @@ FRR_DAEMON_INFO(zebra, ZEBRA,
 );
 /* clang-format on */
 
+void zebra_main_router_started(void)
+{
+	/*
+	 * Clean up zebra-originated routes. The requests will be sent to OS
+	 * immediately, so originating PID in notifications from kernel
+	 * will be equal to the current getpid(). To know about such routes,
+	 * we have to have route_read() called before.
+	 * If FRR is gracefully restarting, we either wait for clients
+	 * (e.g., BGP) to signal GR is complete else we wait for specified
+	 * duration.
+	 */
+	zrouter.startup_time = monotime(NULL);
+	zrouter.rib_sweep_time = 0;
+	zrouter.graceful_restart = zebra_di.graceful_restart;
+	if (!zrouter.graceful_restart)
+		event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL);
+	else {
+		int gr_cleanup_time;
+
+		gr_cleanup_time = zebra_di.gr_cleanup_time ? zebra_di.gr_cleanup_time
+							   : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME;
+		event_add_timer(zrouter.master, rib_sweep_route, NULL, gr_cleanup_time,
+				&zrouter.t_rib_sweep);
+	}
+
+	zserv_start(zserv_path);
+}
+
 /* Main startup routine. */
 int main(int argc, char **argv)
 {
 	// int batch_mode = 0;
-	char *zserv_path = NULL;
 	struct sockaddr_storage dummy;
 	socklen_t dummylen;
 	bool asic_offload = false;
 	bool v6_with_v4_nexthop = false;
 	bool notify_on_ack = true;
 
+	zserv_path = NULL;
+
 	vrf_configure_backend(VRF_BACKEND_VRF_LITE);
 
 	frr_preinit(&zebra_di, argc, argv);
@@ -475,31 +506,11 @@ int main(int argc, char **argv)
 	*/
 	frr_config_fork();
 
-	/* After we have successfully acquired the pidfile, we can be sure
-	*  about being the only copy of zebra process, which is submitting
-	*  changes to the FIB.
-	*  Clean up zebra-originated routes. The requests will be sent to OS
-	*  immediately, so originating PID in notifications from kernel
-	*  will be equal to the current getpid(). To know about such routes,
-	*  we have to have route_read() called before.
-	*  If FRR is gracefully restarting, we either wait for clients
-	*  (e.g., BGP) to signal GR is complete else we wait for specified
-	*  duration.
-	*/
-	zrouter.startup_time = monotime(NULL);
-	zrouter.rib_sweep_time = 0;
-	zrouter.graceful_restart = zebra_di.graceful_restart;
-	if (!zrouter.graceful_restart)
-		event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL);
-	else {
-		int gr_cleanup_time;
-
-		gr_cleanup_time = zebra_di.gr_cleanup_time
-					  ? zebra_di.gr_cleanup_time
-					  : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME;
-		event_add_timer(zrouter.master, rib_sweep_route, NULL,
-				gr_cleanup_time, &zrouter.t_rib_sweep);
-	}
+	/*
+	 * After we have successfully acquired the pidfile, we can be sure
+	 * about being the only copy of zebra process, which is submitting
+	 * changes to the FIB.
+	 */
 
 	/* Needed for BSD routing socket. */
 	pid = getpid();
@@ -510,9 +521,6 @@ int main(int argc, char **argv)
 	/* Start the ted module, before zserv */
 	zebra_opaque_start();
 
-	/* Start Zebra API server */
-	zserv_start(zserv_path);
-
 	/* Init label manager */
 	label_manager_init();
 
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index ffd749fcf17e..d6ed0cc40564 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -123,6 +123,17 @@ void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx)
 		vlan_read(zns);
 		kernel_read_pbr_rules(zns);
 		kernel_read_tc_qdisc(zns);
+
+		/*
+		 * At this point FRR has requested and read a bunch
+		 * of data from the dplane about initial state of
+		 * the system.  Zebra now needs to initialize
+		 * the gr subsystem ( or the route sweeping
+		 * subsystem ) to allow that to properly work.
+		 * This must be done *immediately* after the
+		 * load of all data from the underlying dplane.
+		 */
+		zebra_main_router_started();
 		break;
 	}
 }
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index c86c6be1ef56..a637c3214e06 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -329,6 +329,8 @@ static inline uint8_t if_netlink_get_frr_protodown_r_bit(void)
 	return zrouter.protodown_r_bit;
 }
 
+extern void zebra_main_router_started(void);
+
 /* zebra_northbound.c */
 extern const struct frr_yang_module_info frr_zebra_info;