diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 8a97374e..fe4f5814 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -3238,6 +3238,7 @@ pre_connect_restore(struct options *o, struct
gc_arena *gc)

     o->push_continuation = 0;
     o->push_option_types_found = 0;
+    o->push_update_options_found = 0;
     o->imported_protocol_flags = 0;
 }

diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index bd013dba..ca94b004 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -559,6 +559,7 @@ struct options
     bool pull; /* client pull of config options from server */
     int push_continuation;
     unsigned int push_option_types_found;
+    unsigned int push_update_options_found; /* tracks which option
types have been reset in current PUSH_UPDATE sequence */
     const char *auth_user_pass_file;
     bool auth_user_pass_file_inline;
     struct options_pre_connect *pre_connect;
diff --git a/src/openvpn/options_parse.c b/src/openvpn/options_parse.c
index bb5b4049..99d096b0 100644
--- a/src/openvpn/options_parse.c
+++ b/src/openvpn/options_parse.c
@@ -517,7 +517,12 @@ apply_push_options(struct context *c, struct
options *options, struct buffer *bu
     int line_num = 0;
     const char *file = "[PUSH-OPTIONS]";
     const msglvl_t msglevel = D_PUSH_ERRORS | M_OPTERR;
-    unsigned int update_options_found = 0;
+
+    /*
+     * Use persistent push_update_options_found from options struct to track
+     * which option types have been reset across continuation messages.
+     * This prevents routes from being reset on each continuation message.
+     */

     while (buf_parse(buf, ',', line, sizeof(line)))
     {
@@ -565,7 +570,7 @@ apply_push_options(struct context *c, struct
options *options, struct buffer *bu
             else
             {
                 update_option(c, options, p, false, file, line_num,
0, msglevel, permission_mask,
-                              option_types_found, es, &update_options_found);
+                              option_types_found, es,
&options->push_update_options_found);
             }
         }
     }
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index 7852d360..d0601871 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -540,16 +540,19 @@ incoming_push_message(struct context *c, const
struct buffer *buffer)
             }
             else
             {
-                if (!option_types_found)
+                /* Use accumulated option_types_found for the entire
PUSH_UPDATE sequence */
+                if (!c->options.push_option_types_found)
                 {
                     msg(M_WARN, "No updatable options found in
incoming PUSH_UPDATE message");
                 }
-                else if (!do_update(c, option_types_found))
+                else if (!do_update(c, c->options.push_option_types_found))
                 {
                     msg(D_PUSH_ERRORS, "Failed to update options");
                     goto error;
                 }
             }
+            /* Clear push_update_options_found for next PUSH_UPDATE sequence */
+            c->options.push_update_options_found = 0;
         }
         event_timeout_clear(&c->c2.push_request_interval);
         event_timeout_clear(&c->c2.wait_for_connect);
diff --git a/tests/unit_tests/openvpn/test_push_update_msg.c
b/tests/unit_tests/openvpn/test_push_update_msg.c
index 6ef12668..1a8b1542 100644
--- a/tests/unit_tests/openvpn/test_push_update_msg.c
+++ b/tests/unit_tests/openvpn/test_push_update_msg.c
@@ -54,6 +54,20 @@ options_postprocess_pull(struct options *options,
struct env_set *es)
     return true;
 }

+/*
+ * Counters to track route accumulation across continuation messages.
+ * Used to verify the bug where update_options_found resets per message.
+ */
+static int route_reset_count = 0;
+static int route_add_count = 0;
+
+static void
+reset_route_counters(void)
+{
+    route_reset_count = 0;
+    route_add_count = 0;
+}
+
 bool
 apply_push_options(struct context *c, struct options *options, struct
