Errors — ovn-bgp-agent — branch stable/2026.2
Branch
stable/2026.2@f770768b41dc(7.0.0-2-gf770768) — repository https://opendev.org/openstack/ovn-bgp-agent — analysed on 2026-10-28 External references:ovsdbapp:= ovsdbappstable/2026.2@0fb5a1b9a675.
The agent has no client: no error ever reaches a caller as a status code. An error shows up in exactly three ways, which this file catalogues:
- a log line (the only operator-visible signal; there is no status written back to OVN or Neutron);
- a missing or stale announcement in BGP (the IP is not, or no longer, reachable), repaired at best by the next
sync; - the process stopping (start-up failures,
sys.exit(1)).
1. Exception catalogue
Base class OVNBGPAgentException: message % kwargs, __str__ returns it (ovn_bgp_agent/exceptions.py:18-33). The RuntimeError subclasses take an optional preformatted message (ovn_bgp_agent/exceptions.py:123-160).
| Exception | Message template | Situation | Raised at | Caught at / effect |
|---|---|---|---|---|
ConfOptionRequired | Required driver conf option missing: CONF.%(option)s | NB driver with exposing_method = vrf and evpn_local_ip unset, when the first EVPN bridge is built | ovn_bgp_agent/drivers/openstack/utils/evpn.py:46 | not caught in wire → the whole sync fails, logged Unexpected exception while running the sync (ovn_bgp_agent/agent.py:54-55); repeats every reconcile_interval |
UnsupportedWiringConfig | No wiring support for exposing_method %(method)s. | NB driver with exposing_method l2vni or dynamic (accepted by the option's choices) | ovn_bgp_agent/drivers/openstack/utils/wire.py:44 | sync fails every cycle, nothing is exposed by sync |
InvalidPortIP | OVN port with invalid IP: %(ip)s. | an IP/CIDR that netaddr cannot parse when building an ip rule | ovn_bgp_agent/utils/linux_net.py:693 | caught in wiring: LOG.exception("Invalid IP to create a rule …"), wiring returns False, the IP is not announced (ovn_bgp_agent/drivers/openstack/utils/wire.py:686-689, ovn_bgp_agent/drivers/openstack/utils/wire.py:838-841) |
PortNotFound | OVN port was not found: %(port)s. | (a) ovs-vsctl get Interface <port> ofport fails or returns [] — the patch port of a provider network does not exist yet on this node (no VM of that network was ever bound here); retried every 1 s for 5 s (ovn_bgp_agent/drivers/openstack/utils/ovs.py:53-70); (b) the peer of an EVPN patch port has no row (ovn_bgp_agent/drivers/openstack/utils/ovn.py:655-661) | ovn_bgp_agent/drivers/openstack/utils/ovs.py:64, ovn_bgp_agent/drivers/openstack/utils/ovs.py:69, ovn_bgp_agent/drivers/openstack/utils/ovn.py:661 | (a) not caught by _wire_provider_port_underlay, which catches PatchPortNotFound instead (ovn_bgp_agent/drivers/openstack/utils/wire.py:699-706): it propagates to the driver's broad except Exception → LOG.exception("Unexpected exception while wiring provider port: …"), IP not announced although the rule/route were already added (§ 4) |
DatapathNotFound | Datapath was not found: %(datapath)s. | SB query on a datapath UUID the IDL no longer knows (ValueError from ovsdbapp): network/router deleted while events are still being processed | ovn_bgp_agent/drivers/openstack/utils/ovn.py:487, ovn_bgp_agent/drivers/openstack/utils/ovn.py:503, ovn_bgp_agent/drivers/openstack/utils/ovn.py:515 | expose paths: DEBUG … not being exposed as its datapath %s was removed, skip; withdraw of a VM: treated as a provider network to force the withdrawal (ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py:681-693); subnet withdraw: falls back to the local cr-lrp cache (ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py:1117-1139) |
PatchPortNotFound | Patch port not found for localnet: %(localnet)s. | never raised in this branch | — | caught at ovn_bgp_agent/drivers/openstack/utils/wire.py:701 (dead handler) |
ExposeDeniedForAddressScope | Exposing addresses %(addresses)s with address scopes %(address_scopes)s was denied, required scopes: %(configured_scopes)s | NB: every CIDR of a router interface fails the address_scopes filter | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1027, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1103 | caught: DEBUG Not exposing subnet CIDR's %s: %s / Withdraw router lsp failure … (ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:897-902, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:951-957) |
WireFailure | Failure with wiring for CIDR %(cidr)s: %(message)s | NB: wiring a tenant subnet returned False (no bridge, EVPN device not set up) or raised; always with exposing_method = ovn (wire_lrp_port returns None, ovn_bgp_agent/drivers/openstack/utils/wire.py:820-828) | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1053, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1056 | caught, DEBUG only: the subnet is silently not exposed |
UnwireFailure | Failure with removing wiring for CIDR %(cidr)s: %(message)s | NB: unwiring a tenant subnet failed | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1122, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:1124 | caught, DEBUG; withdrawal of tenant VM IPs continues |
MacAddressNotFound | Addresses column is empty or not set for port %(lsp)s | LSP with empty addresses | ovn_bgp_agent/drivers/openstack/utils/port.py:51 | not caught in event _run → Unexpected exception while running the event action |
IpAddressNotFound | Addresses column has no IP addresses or is not set for port %(lsp)s | LSP with a MAC but no IP | ovn_bgp_agent/drivers/openstack/utils/port.py:57 | caught in matches and sync (port skipped) |
RoutingTablesFileNotFound | Default routing tables file not found at %(path)s. Please ensure iproute2 package is properly installed. | neither /etc/iproute2/rt_tables nor /usr/share/iproute2/rt_tables exists | ovn_bgp_agent/privileged/linux_net.py:340 | sync fails every cycle |
NetworkInterfaceNotFound | Network interface %(device)s not found | netlink ENODEV or link lookup miss | ovn_bgp_agent/privileged/linux_net.py:353, ovn_bgp_agent/privileged/linux_net.py:440, ovn_bgp_agent/utils/linux_net.py:67 | expected by ensure_* (create on miss), by del_ip_route (DEBUG, routes assumed gone), by add_ip_route (creates the VLAN device); elsewhere propagates |
IpAddressAlreadyExists | IP address %(ip)s already configured on %(device)s. | EEXIST on address add | ovn_bgp_agent/privileged/linux_net.py:365 | ignored by callers (idempotent add) (ovn_bgp_agent/utils/linux_net.py:663-669) |
InterfaceAlreadyExists, InterfaceOperationNotSupported, InvalidArgument | Interface %(device)s already exists. / Operation not supported on interface %(device)s. / Invalid parameter/value used on interface %(device)s. | netlink EEXIST / EOPNOTSUPP / EINVAL on link operations | ovn_bgp_agent/privileged/linux_net.py:355-359 | propagate (sync/event fails, logged) |
nb_exceptions.NATNotFound | free text, e.g. NAT entry for port %s not found, … does not contain network ID in its external_ids, … does not have external_mac set, Port %s has no NAT entry | NB: FIP port without a usable NAT row; centralized NAT without gateway_port | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:679-691, ovn_bgp_agent/drivers/openstack/utils/nat.py:23 | caught in FIP events/sync: DEBUG … does not have all data required in its NAT entry; in FipOnCRLRPBaseEvent.match_fn it escapes → ovsdbapp Event not matched due to this exception |
nb_exceptions.ChassisNotFound | ("Gateway port %s has no chassis set in its status column.", <row>) (tuple: the message is not formatted) | centralized NAT whose gateway port has no hosting-chassis | ovn_bgp_agent/drivers/openstack/utils/nat.py:31 | raised from match_fn → ovsdbapp logs Event not matched due to this exception |
RuntimeError | Centralized routing requires gateway_port column in the OVN_Northbound schema. Please update OVN to 23.09.0 or later. | NB driver, centralized FIPs, old OVN schema | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:56 | at start: agent start fails; on flag change: event lost (logged by ovsdbapp) |
RuntimeError | The exposer does not have distributed flag set yet | NAT exposer used before the mode is known | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:66, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:70 | not reachable in normal start order [inferred] |
NotImplementedError | Distributed NAT is not implemented yet. | nat_exposer in distributed mode (events of § 3.4 centralized are unregistered then) | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:87, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:108 | not reachable [inferred] |
RuntimeError | Static MAC Binding entry for port %s and ip %s exists / … does not exist / Unexpected duplicates in database for port %s and ip %s | local NB transaction (exposing_method = ovn) | ovn_bgp_agent/drivers/openstack/utils/ovn.py:194-251 | callers use may_exist/if_exists, so only duplicates can surface; caught by the driver's broad handler |
KeyError | Could not locate EVPN for bridge %s and/or vlan %s | NB vrf: no EVPN bridge set up for the bridge/VLAN of the port | ovn_bgp_agent/drivers/openstack/utils/evpn.py:541 | caught in wire: WARNING EVPN has not been setup for bridge %s with vlan device %s …, IP not exposed (ovn_bgp_agent/drivers/openstack/utils/wire.py:713-720); not caught in bgp_utils.announce_ips for tenant IPs (ovn_bgp_agent/drivers/openstack/utils/bgp.py:35) → event error |
NotImplementedError | — | stretched driver expose_remote_ip/withdraw_remote_ip | ovn_bgp_agent/drivers/openstack/ovn_stretched_l2_bgp_driver.py:535, ovn_bgp_agent/drivers/openstack/ovn_stretched_l2_bgp_driver.py:539 | never called |
SystemExit(1) | log No more routing tables available for bridge %s at %s | 252 routing table numbers all used in /etc/iproute2/rt_tables | ovn_bgp_agent/utils/linux_net.py:265 | process exits from inside sync (raised in a looping-call thread: SystemExit is a BaseException, not caught by except Exception) [inferred] |
Errors from libraries
| Origin | Error | Situation | Effect |
|---|---|---|---|
processutils | ProcessExecutionError | vtysh, sysctl, ip -6 nei, ovs-vsctl, ovs-ofctl exit code ≠ 0 | logged Unable to execute %s. Exception: %s / Unable to execute vtysh with %s. Exception: %s (ovn_bgp_agent/privileged/vtysh.py:31-33, ovn_bgp_agent/privileged/linux_net.py:171-177) and re-raised; ovs-ofctl is retried once with OpenFlow13 (ovn_bgp_agent/privileged/ovs_vsctl.py:40-44); ip -6 nei del proxy returning "No such file or directory" is ignored (ovn_bgp_agent/privileged/linux_net.py:228-235) |
| pyroute2 | NetlinkError | any other errno than those translated (§ 1) | propagates |
| pyroute2 | NetlinkDumpInterrupted | concurrent change during a dump | retried with backoff up to 8 s (ovn_bgp_agent/utils/linux_net.py:49-53) |
| ovsdbapp / ovs | connection errors, TimeoutException | OVN DB unreachable | the IDL reconnects by itself; SB drivers resync on the next Chassis_Private CREATE (§ 05 1.3); NB driver waits for the timer |
| oslo.privsep | daemon start failure | root_helper cannot run privsep-helper | first privileged call fails; agent cannot work [inferred] |
2. Asynchronous errors (no exception reaches anything)
- Event errors:
Unexpected exception while running the event actionwith traceback (ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py:31-36); for events overridingrun, ovsdbapp'sUnexpected exception in notify_loop(ovsdbapp:ovsdbapp/event.py:205-208). The event is dropped. - Match errors: ovsdbapp's
Event not matched due to this exception:(ovsdbapp:ovsdbapp/event.py:153-158). Two places hit it by construction:evpn_watcher.SubnetRouterAttachedEvent.match_fnreferencesconstants.constants.OVN_EVPN_AS_EXT_ID_KEY(ovn_bgp_agent/drivers/openstack/watchers/evpn_watcher.py:97); theAttributeErroris caught by the function's ownexceptand returns False. Effect: an UPDATE that addsneutron_bgpvpn:asto a port that already had the VNI never matches; only the nextsyncexposes it.FipOnCRLRPBaseEventraisingChassisNotFound/NATNotFound(above).
- Sync errors:
Unexpected exception while running the sync: %s/… frr sync: %s(ovn_bgp_agent/agent.py:52-64). A failing sync stops at the failing step: the cleanup phase (end ofsync) is then skipped, so leftovers stay until a sync completes. - Silent non-exposure (no error, DEBUG or nothing): missing EVPN annotations, address scope mismatch,
require_snat_disabled_for_tenant_networks(INFOAll ips (%s) were removed due to SNAT requirement …,ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:885-895), FRR router-id unknown (ERRORUnknown router-id, needed for route leaking,ovn_bgp_agent/drivers/openstack/utils/frr.py:182-186: the VRF leak is not configured and no IP announced throughbgp_nicreaches the default BGP instance).
3. Key log messages
| Level | Message | Situation | Defined at |
|---|---|---|---|
| INFO | Loaded chassis %s. | start | ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py:82 |
| INFO | Running reconciliation loop to ensure routes/rules are in place. | each sync | ovn_bgp_agent/agent.py:50 |
| INFO | Running reconciliation loop to ensure frr configuration is in place. | each frr_sync (every 15 s) | ovn_bgp_agent/agent.py:58 |
| INFO | Add VRF leak for VRF %s on router bgp %s | each frr_sync | ovn_bgp_agent/drivers/openstack/utils/frr.py:181 |
| INFO | Connection to OVSDB established, doing a full sync | SB reconnection | ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py:93 |
| WARNING | Agent did not find %s configuration in the OVN Northbound NB_Global table … | NB start without neutron:fip-distributed | ovn_bgp_agent/drivers/openstack/utils/ovn.py:446-453 |
| WARNING | OVN version does not include support for status information. Therefore router ports and tenant IPs cannot be exposed. | NB driver on OVN < 23.09 | ovn_bgp_agent/drivers/openstack/utils/ovn.py:371-373 |
| WARNING | Removing IPs %s from %s as they are not expected to be exposed. | NB sync cleanup | ovn_bgp_agent/drivers/openstack/utils/wire.py:544-545 |
| WARNING | Patch port %s for bridge %s not found. … | unreachable as written (§ 1 PortNotFound) | ovn_bgp_agent/drivers/openstack/utils/wire.py:702-705 |
| WARNING | EVPN has not been setup for bridge %s with vlan device %s. … | NB vrf, network without EVPN annotations | ovn_bgp_agent/drivers/openstack/utils/wire.py:716-719 |
| WARNING | NIC ports (%s) not found for bridge %s. … | exposing_method = ovn, external_nics not on the bridge | ovn_bgp_agent/drivers/openstack/utils/wire.py:470-473 |
| WARNING | Incorrect bridge mapping settings: %s | malformed ovn-bridge-mappings entry | ovn_bgp_agent/utils/helpers.py:24 |
| ERROR | Unknown router-id, needed for route leaking | no bgp_router_id and FRR has none | ovn_bgp_agent/drivers/openstack/utils/frr.py:185 |
| ERROR | No more routing tables available for bridge %s at %s | table numbers exhausted (then exit) | ovn_bgp_agent/utils/linux_net.py:263 |
| ERROR | NAT entry %(nat)s does not have %(fip_net)s set in external_ids | NAT without neutron:fip_network_id | ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py:928, ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py:141 |
| ERROR | EVPN information at router port (vni: %s, as: %s) does not match with information at subnet gateway port: %s | EVPN annotations inconsistent | ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py:406 |
| ERROR | EVPN device must have an IP associated for the VXLAN local ip | no VXLAN source IP | ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py:606, ovn_bgp_agent/drivers/openstack/utils/evpn.py:44 |
| ERROR | Unable to execute %s %s | an ovs-* command failed | ovn_bgp_agent/privileged/ovs_vsctl.py:32 |
| EXCEPTION | Unexpected exception while wiring provider port: %s | any error while wiring (port left un-announced) | ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py:349-352, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:413-416 |
4. Defects found while reading or running
| # | Defect | Effect | Where |
|---|---|---|---|
| D1 | _wire_provider_port_underlay catches PatchPortNotFound, but get_device_port_at_ovs raises PortNotFound | the first VM of a provider network on a node: rule and route are installed, then the exception aborts before announce_ips; the IP is announced only at a later sync once the patch port exists | ovn_bgp_agent/drivers/openstack/utils/wire.py:699-706, ovn_bgp_agent/drivers/openstack/utils/ovs.py:53-70 |
| D2 | linux_net.set_device_status passes ndb= to the privileged set_device_state(device, state), which has no such parameter | SB EVPN driver, VLAN provider network: TypeError when building the devices; the gateway is never exposed | ovn_bgp_agent/utils/linux_net.py:856-858, ovn_bgp_agent/privileged/linux_net.py:54-55, ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py:625 |
| D3 | constants.constants.OVN_EVPN_AS_EXT_ID_KEY | see § 2 | ovn_bgp_agent/drivers/openstack/watchers/evpn_watcher.py:97 |
| D4 | update_subnet computes the old IPs with if old.mac or len(old.mac[0]…) (or instead of and) | IndexError when old.mac is empty; event lost | ovn_bgp_agent/drivers/openstack/ovn_stretched_l2_bgp_driver.py:235-239 |
| D5 | _update_network replaces propagated_lrp_ports[...]["subnets"] with only the added subnets | after a subnet is added to a router port, withdrawing the port forgets the earlier subnets' routes until the next sync | ovn_bgp_agent/drivers/openstack/ovn_stretched_l2_bgp_driver.py:458-463 |
| D6 | get_lrp_ports_on_provider builds a list but returns nothing | unused in this branch | ovn_bgp_agent/drivers/openstack/utils/ovn.py:640-648 |
| D7 | get_bridge_vlans logs "deleted" when the bridge is missing but continues with link=None | lists all links' VLAN ids instead of none [inferred] | ovn_bgp_agent/privileged/linux_net.py:464-478 |
| D8 | _run_vtysh_config_with_tempfile: if NamedTemporaryFile fails, the handler references the unbound f | UnboundLocalError hides the I/O error | ovn_bgp_agent/drivers/openstack/utils/frr.py:122-132 |
| D9 | ChassisNotFound(msg, row) builds a 2-tuple message | unreadable log | ovn_bgp_agent/drivers/openstack/utils/nat.py:31-33 |
| D10 | l2vni and dynamic are valid choices of exposing_method but rejected at sync | misconfiguration detected only at run time, every 300 s | ovn_bgp_agent/config.py:130-145, ovn_bgp_agent/drivers/openstack/utils/wire.py:44 |
| D11 | _SYNC_STATE_LOCK read-locks are never paired with a write lock | no protection; see 05 § 1.2 | ovn_bgp_agent/drivers/openstack/watchers/bgp_watcher.py:26 |
| D12 | ovn_local_lrps != [] compared with a dict | always true; no filtering in match_fn | ovn_bgp_agent/drivers/openstack/watchers/bgp_watcher.py:279, ovn_bgp_agent/drivers/openstack/watchers/evpn_watcher.py:163 |
| D13 | get_ovn_vip_port slices neutron:port_name without checking it exists | TypeError on any unbound MAC-less port without that key; LB event lost | ovn_bgp_agent/drivers/openstack/utils/ovn.py:759-763 |
| D14 | the node-local NB IDL does not register BFD but bfd_add is called | exposing_method = ovn with peer_ips likely fails at sync [inferred, not run] | ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:47-51, ovn_bgp_agent/drivers/openstack/utils/wire.py:281-293 |
| D15 | vrf_reconfigure fills local_ip from CONF.evpn_local_ip only | without evpn_local_ip (allowed by the SB EVPN driver, which then takes the VXLAN source from lo/evpn_nic), FRR receives rd None:<vni> — confirmed by running (scenario frr-and-evpn-renderings) | ovn_bgp_agent/drivers/openstack/utils/frr.py:63-67, ovn_bgp_agent/drivers/openstack/utils/frr.py:210-214 |
| D16 | ensure_base_wiring_config does routing_tables = routing_tables or {}; the NB driver passes its empty dict, which is replaced by a new one and never filled (regression of commit ccf4c29, in every tag since 5.0.0) | **NB driver with underlay**: wiring a provider IP raises KeyError (swallowed: Unexpected exception while wiring provider port), nothing is announced by sync; sync itself fails in cleanup_wiring with KeyError: '<bridge>', so leftovers are never cleaned; events that wire IPs fail the same way — confirmed by running (scenario defect-d16-nb-underlay-routing-tables); the unit tests mock this function | ovn_bgp_agent/drivers/openstack/utils/wire.py:34-38, ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py:297-300 |
D1, D2, D15 and D16 were reproduced by the scenarios of _rewrite/side-effects_stable-2026.2.json (07); the others were found by reading.
Source: reverse-spec-ovn-bgp-agent/02-errors_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.