diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py
index fe24cd77139..d0553d2ebd6 100644
--- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py
+++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py
@@ -891,6 +891,33 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
 
         raise periodics.NeverAgain()
 
+    @periodics.periodic(spacing=600, run_immediately=True)
+    def check_router_default_route_empty_dst_ip(self):
+        """Check routers with default route with empty dst-ip (LP: #2002993).
+        """
+        if not self.has_lock:
+            return
+
+        cmds = []
+        for router in self._nb_idl.lr_list().execute(check_error=True):
+            if not router.external_ids.get(ovn_const.OVN_REV_NUM_EXT_ID_KEY):
+                continue
+            for route in self._nb_idl.lr_route_list(router.uuid).execute(
+                    check_error=True):
+                if (route.nexthop == '' and
+                        (route.ip_prefix == n_const.IPv4_ANY or
+                         route.ip_prefix == n_const.IPv6_ANY)):
+                    cmds.append(
+                        self._nb_idl.delete_static_route(
+                            router.name, route.ip_prefix, ''))
+
+        if cmds:
+            with self._nb_idl.transaction(check_error=True) as txn:
+                for cmd in cmds:
+                    txn.add(cmd)
+
+        raise periodics.NeverAgain()
+
 
 class HashRingHealthCheckPeriodics(object):
 
diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py
index 9a087e6a128..286791f2ffb 100644
--- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py
+++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py
@@ -1264,6 +1264,8 @@ class OVNClient(object):
         # 2. Add default route with nexthop as gateway ip
         lrouter_name = utils.ovn_name(router['id'])
         for gw_info in gateways:
+            if gw_info.gateway_ip is None:
+                continue
             columns = {'external_ids': {
                 ovn_const.OVN_ROUTER_IS_EXT_GW: 'true',
                 ovn_const.OVN_SUBNET_EXT_ID_KEY: gw_info.subnet_id}}
diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py
index 30b7e774c99..1823e986e95 100644
--- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py
+++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py
@@ -16,6 +16,7 @@
 from unittest import mock
 
 from futurist import periodics
+from neutron_lib import constants as n_const
 from neutron_lib import context
 from neutron_lib.db import api as db_api
 from oslo_config import cfg
@@ -797,3 +798,36 @@ class TestDBInconsistenciesPeriodics(testlib_api.SqlTestCaseLight,
         expected_calls = [mock.call('Logical_Switch_Port', lsp0.uuid,
                                     ('type', constants.LSP_TYPE_VIRTUAL))]
         nb_idl.db_set.assert_has_calls(expected_calls)
+
+    def test_check_router_default_route_empty_dst_ip(self):
+        nb_idl = self.fake_ovn_client._nb_idl
+        route0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+            attrs={'ip_prefix': n_const.IPv4_ANY,
+                   'nexthop': '10.42.0.1'})
+        route1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+            attrs={'ip_prefix': n_const.IPv4_ANY,
+                   'nexthop': ''})
+        route2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+            attrs={'ip_prefix': n_const.IPv6_ANY,
+                   'nexthop': '2001:db8:42::1'})
+        route3 = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+            attrs={'ip_prefix': n_const.IPv6_ANY,
+                   'nexthop': ''})
+        router0 = fakes.FakeOvsdbRow.create_one_ovsdb_row()
+        router1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+                attrs={
+                    'external_ids': {constants.OVN_REV_NUM_EXT_ID_KEY: 1}
+                })
+        nb_idl.lr_list.return_value.execute.return_value = (router0, router1)
+        nb_idl.lr_route_list.return_value.execute.return_value = (
+            route0, route1, route2, route3)
+        self.assertRaises(
+            periodics.NeverAgain,
+            self.periodic.check_router_default_route_empty_dst_ip)
+        nb_idl.delete_static_route.assert_has_calls([
+            mock.call(router1.name, route1.ip_prefix, route1.nexthop),
+            mock.call(router1.name, route3.ip_prefix, route3.nexthop),
+        ])
+        self.assertEqual(
+            2,
+            nb_idl.delete_static_route.call_count)
diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py
index aff755e0696..15998320f9b 100644
--- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py
+++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py
@@ -20,7 +20,9 @@ from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
 from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_client
 from neutron.tests import base
 from neutron.tests.unit import fake_resources as fakes
+from neutron_lib.api.definitions import l3
 from neutron_lib.api.definitions import portbindings
+from neutron_lib import constants as const
 
 
 class TestOVNClientBase(base.BaseTestCase):
@@ -33,6 +35,70 @@ class TestOVNClientBase(base.BaseTestCase):
         self.ovn_client = ovn_client.OVNClient(self.nb_idl, self.sb_idl)
 
 
+class TestOVNClient(TestOVNClientBase):
+
+    def setUp(self):
+        super(TestOVNClient, self).setUp()
+        self.get_plugin = mock.patch(
+            'neutron_lib.plugins.directory.get_plugin').start()
+
+    def test__add_router_ext_gw_default_route(self):
+        plugin = mock.MagicMock()
+        self.get_plugin.return_value = plugin
+        subnet = {
+            'subnet_id': 'fake-subnet-id',
+            'gateway_ip': '10.42.0.1',
+            'ip_version': const.IP_VERSION_4,
+        }
+        plugin.get_subnet.return_value = subnet
+        router = {
+            'id': 'fake-router-id',
+            l3.EXTERNAL_GW_INFO: {
+                'external_fixed_ips': [{
+                        'subnet_id': subnet.get('subnet_id'),
+                        'ip_address': '10.42.0.42'}],
+            },
+            'gw_port_id': 'fake-port-id',
+        }
+        networks = mock.MagicMock()
+        txn = mock.MagicMock()
+        self.assertEqual(
+            self.get_plugin().get_port(),
+            self.ovn_client._add_router_ext_gw(router, networks, txn))
+        self.nb_idl.add_static_route.assert_called_once_with(
+            'neutron-' + router['id'],
+            ip_prefix='0.0.0.0/0',
+            nexthop='10.42.0.1',
+            external_ids={
+                'neutron:is_ext_gw': 'true',
+                'neutron:subnet_id': subnet['subnet_id']})
+
+    def test__add_router_ext_gw_no_default_route(self):
+        plugin = mock.MagicMock()
+        self.get_plugin.return_value = plugin
+        subnet = {
+            'subnet_id': 'fake-subnet-id',
+            'gateway_ip': None,
+            'ip_version': const.IP_VERSION_4
+        }
+        plugin.get_subnet.return_value = subnet
+        router = {
+            'id': 'fake-router-id',
+            l3.EXTERNAL_GW_INFO: {
+                'external_fixed_ips': [{
+                        'subnet_id': subnet.get('subnet_id'),
+                        'ip_address': '10.42.0.42'}],
+            },
+            'gw_port_id': 'fake-port-id',
+        }
+        networks = mock.MagicMock()
+        txn = mock.MagicMock()
+        self.assertEqual(
+            self.get_plugin().get_port(),
+            self.ovn_client._add_router_ext_gw(router, networks, txn))
+        self.nb_idl.add_static_route.assert_not_called()
+
+
 class TestOVNClientDetermineBindHost(TestOVNClientBase):
 
     def setUp(self):