Hello, Thanks for sharing this incident with the community. On May 17, because of an incorrect filter configuration, routers of AS202734 exported a number of prefixes from its internal routing table to the route collector of the Hurricane Electric BGP looking glass (bgp.he.net). For BGP sessions with upstream transit providers (real routers), AS202734 uses a tighter set of filters, and export only prefixes that are within a small number of whitelisted "ANNOUNCED_v4/v6" subnets. Thus, none of the said prefixes were ever exported to real routers on the internet, and this incident did not affect any public routing infrastructure. However, this incident might have triggered a number of automated emails from the HE.net looking glass to those who subscribed to updates about the affected prefixes. These are truly what one would describe as "false alarms". If you did receive one of these emails and was alerted, you have my apologies. For the benefit of the NANOG community, here is a detailed description of what triggered this "false alarm" incident. AS202734/AS402333 runs a custom fork of BIRD3 as the routing control plane for its routers. The configuration files for these routers are rendered automatically from a Jinja template- and the aforementioned export filter is no exception. The same filter template controls both routes exported to transit providers and public looking glass route collectors such as bgp.he.net. When AS202734 receives a prefix from its upstreams or IX peers, the import filter would automatically tag the route with a large community of the form ({{ cold_potato_asn }}, {{ router_ld2_id }}, {{ neighbor_asn }})). This community identifies the source of the route, as well as the AS202734 router where the prefix was learned. BGP looking glasses- bgp.he.net, bgptools, etc.- typically require a full table to be exported- not just routes whitelisted for announcement to upstreams. Since the whitelist filter no longer applies, some alternative method would be necessary to filter out routes that are in the iBGP table, but are not learned from peers or upstreams- these include internal routing infrastructure prefixes, as well as other types of routing optimizations that should not be exported to the public internet. It seems like a natural option to build this filter around the aforementioned BGP Large Community, which is supposedly applied only to routes learned from other networks, and not from the internal infrastructure. As seen in line 30 of the Jinja template below, "session_export_non_local" evaluates to True for route collectors (but not for upstream transit providers,) and routes would be accepted for export to the collectors even if they are not in the "announced" whitelist- as long as they are tagged with this large community when learned from peers or upstream. In the filter for regular upstream transit providers, the original whitelist still applies. This setup worked just as expected for months, and routes observed at AS202734 were visible through various public looking glasses, helping other networks understand the reachability of their prefixes. However, up to this point, there is no clear way to determine from which session or geographic region was a particular prefix exported- either to the route collector or to a real upstream. To resolve this, it seems natural to reuse the same large community- tagging exported routes with geographical router info and session info in the export filter. See line 15 of the code snippet below: # v6 version of the filter is shown; the filter for v4 follows the same logic 1 filter ebgp_export_v6_{{ session_id }} { 2 {% for community in session_communities %} 3 {% set community_value = community if community is string else (community | join(', ')) %} 4 bgp_community.add(({{ community_value }})); 5 {% endfor %} 6 {% for community in session_large_communities %} 7 {% set community_value = community if community is string else (community | join(', ')) %} 8 bgp_large_community.add(({{ community_value }})); 9 {% endfor %} 10 {% for community in session_ext_communities %} 11 {% set community_value = community if community is string else (community | join(', ')) %} 12 bgp_ext_community.add(({{ community_value }})); 13 {% endfor %} 14 15 # Added on the day of the incident: # bgp_large_community.add(({{ cold_potato_asn }}, {{ router_ld2_id }}, {{ neighbor_asn }})); 16 17 {% for prepend in session_prepend %} 18 bgp_path.prepend({{ prepend }}); 19 {% endfor %} 20 21 if net = ::/0 then { 22 {% if session_export_default %} 23 accept; 24 {% else %} 25 reject; 26 {% endif %} 27 } 28 29 if (net ~ ANNOUNCED_v6) then accept; 30 {% if session_export_non_local %} 31 if (bgp_large_community ~ [ ({{ cold_potato_asn }}, *, *) ]) then accept; 32 {% endif %} 33 reject; As you might have anticipated, the issue is that this newly-added BGP large community applies to all prefixes routes in the table, and not just those directly learned from upstream/peers. As a result, a large number of internal-only prefixes (4,622 to be exact) with missing BGP PATH info also received this large community. While the whitelisting mechanism prevented these prefixes from being announced to upstream transit providers, these prefixes were announced to route collectors of BGP.he.net from two of the AS202734 routers. The fix, as you might expect, is to move the filter "accept" logic into its own function, and apply any information communities only after if the "accept" function returned true and no "reject" filter was triggered. After deploying this fix and testing extensively, AS202734 is now once again contributing data to the public looking glasses- with the BGP large community included to help engineers of other networks better understand the reachability of their prefixes across geographies. To avoid similar incidents in the future, a staging environment paired with extensive code reviews might be helpful. I hereby thank the NANOG community and in particular Zhong Miao, the Independent Security Researcher, for bringing this issue to my attention so swiftly. I also appreciate comments from the community regarding best practices to make the deployment process more reliable and secure. Regards, Jacob-Junqi Tian May. 23, 2026.