· 7 min read

RPKI and ROA Explained: Create ROAs, Fix Max-Length Errors

RPKI (Resource Public Key Infrastructure) is a cryptographic system that lets the holder of an IP block prove which AS number is allowed to originate it in BGP. A ROA (Route Origin Authorization) is the signed record that carries that proof: a prefix, a maximum prefix length, and an origin ASN. Networks that run route origin validation compare every BGP announcement against those records and drop the ones that contradict them.

If your announcement suddenly stops working from some parts of the internet, an RPKI-invalid state is one of the first things to check. This guide covers how validation works, how to create a ROA, why max-length mistakes are the most common cause of invalid routes, and how to validate routes on your own router.

How RPKI route origin validation works

The five Regional Internet Registries (AFRINIC, APNIC, ARIN, LACNIC, RIPE NCC) each operate a trust anchor. When you hold address space, you can create ROAs under that trust anchor through your RIR's portal. A validator (also called a relying party) downloads all published ROAs, verifies the signatures, and hands a clean list of validated ROA payloads (VRPs) to your routers over the RPKI-to-Router (RTR) protocol.

For each BGP route, the router returns one of three states (RFC 6811):

State Meaning
Valid A ROA covers the prefix, the origin ASN matches, and the prefix length is within maxLength.
Invalid A ROA covers the prefix, but the origin ASN does not match or the prefix is longer than maxLength.
NotFound No ROA covers the prefix at all.

The key point: NotFound routes are still accepted by almost everyone. Invalid routes are not. Creating a correct ROA moves you from NotFound to Valid. Creating a wrong ROA, or forgetting to update one, moves you to Invalid, which is worse than having no ROA.

Why invalid routes get dropped

Many transit providers, internet exchanges, and large eyeballs networks reject RPKI-invalid routes at the edge. The reasoning is simple. If the registry data says "only AS64496 may originate 192.0.2.0/24," then an announcement of that prefix from AS64511 is either a hijack or a misconfiguration. Dropping it protects the prefix holder and the networks that would otherwise send traffic to the wrong place.

The side effect is that your own mistakes get enforced just as strictly as an attacker's. An invalid route is not "less preferred." In most deployments it is simply not installed.

Creating a ROA

The exact clicks differ per RIR, but the data you enter is always the same.

  1. Confirm you control the resource. You need an account at the RIR (or at your LIR) that holds the allocation or assignment. If you lease the block, the lessor usually controls the ROA and you must ask them to create it.
  2. Decide the origin ASN. This is the ASN that will appear at the end of the AS path when your prefix is announced, for example AS64496.
  3. Decide the prefix and maxLength. For 192.0.2.0/24 announced exactly as a /24, use maxLength 24.
  4. Create the ROA in the portal. - RIPE NCC: LIR Portal or My RIPE, then the RPKI dashboard. - ARIN: ARIN Online, Hosted RPKI (requires accepting the RPA). - APNIC: MyAPNIC, RPKI section. - LACNIC and AFRINIC: the respective member portals.
  5. Wait for propagation. Validators refresh on their own schedules, so a new ROA can take from several minutes to a few hours to be seen everywhere.

A ROA for each prefix looks like this conceptually:

prefix:     192.0.2.0/24
maxLength:  24
origin:     AS64496

prefix:     2001:db8::/32
maxLength:  48
origin:     AS64496

You can have several ROAs for the same prefix with different origin ASNs. This is normal and required when more than one network may legitimately originate it, which brings us to a common trap below.

The max-length mistake

maxLength defines the longest prefix a ROA authorizes. If you leave it at the prefix's own length, announcing anything more specific is invalid.

A typical failure with IPv6:

ROA:          2001:db8::/32  maxLength 32  AS64496
Announcement: 2001:db8:100::/48  origin AS64496
Result:       INVALID (prefix longer than maxLength)

The origin ASN is correct, but the /48 exceeds the authorized length, so the route is invalid. The same happens in IPv4 when you hold a /23, publish a ROA with maxLength 23, and then announce two /24s.

Why not just set maxLength to the maximum?

Setting maxLength to /24 (IPv4) or /48 (IPv6) on everything makes the error disappear, but it widens what a forged announcement can get away with. An attacker can announce a more-specific prefix and prepend your ASN to the path, and the route still validates as Valid. The practical guidance:

Other common causes of invalid routes

Checking a route before and after you announce

Use a public tool such as RIPEstat or bgp.tools to see the RPKI state of your prefix, and check how it looks from different vantage points with a looking glass. Nixcon's public looking glass at lg.nixconllc.com supports BGP route, ping, and traceroute queries from Izmir, Frankfurt, and the US, which is handy for confirming that your announcement is visible.

If you run your own validator, Routinator can check a specific pair directly:

routinator validate --asn 64496 --prefix 192.0.2.0/24

The output tells you valid, invalid (with the reason: wrong ASN or length), or not found.

Validating routes on your own router with BIRD 2

If you receive routes from upstreams, you should reject invalid ones too. First, run a validator that exposes RTR on localhost (Routinator's default RTR port is 3323):

routinator server --rtr 127.0.0.1:3323

Then connect BIRD 2 to it:

roa4 table r4;
roa6 table r6;

protocol rpki rpki1 {
    roa4 { table r4; };
    roa6 { table r6; };
    remote 127.0.0.1 port 3323;
    retry keep 90;
    refresh keep 900;
    expire keep 172800;
}

filter import_rpki {
    if (net.type = NET_IP4 && roa_check(r4, net, bgp_path.last) = ROA_INVALID) then reject;
    if (net.type = NET_IP6 && roa_check(r6, net, bgp_path.last) = ROA_INVALID) then reject;
    accept;
}

Apply import_rpki as a part of your import policy on each eBGP session, together with your usual bogon, prefix-length, and max-prefix filters. FRRouting offers the same capability through its rpki configuration and match rpki invalid in route-maps.

Two operational notes: do not reject NotFound routes, since a large share of the internet is still unsigned, and make sure the validator is monitored. If the RTR session dies and the data expires, your router falls back to treating everything as NotFound.

RPKI when announcing from a VDS

If you announce your own ASN and block from a virtual server, the ROA is the first thing to get right. On Nixcon's BGP-enabled VDS, ASN and prefix ownership are verified automatically using RPKI ROAs and the official RIR/IRR records, and your ASN is added to the AS-NIXCON AS-SET. So the ROA should exist and match your origin ASN before you request the session. For DDoS-protected announcements, see the DDoS protection and firewall page for the available options.

Quick checklist

  1. ROA exists for every prefix you announce.
  2. Origin ASN in the ROA matches the last ASN in your AS path.
  3. maxLength equals the longest prefix you actually announce.
  4. Every ASN that may originate the prefix (including a protection provider) has a ROA.
  5. IRR objects and AS-SET membership are current.
  6. Your own routers reject RPKI-invalid routes from upstreams.
  7. After changes, wait for validators to refresh, then verify from several vantage points.

Frequently asked questions

What is the difference between RPKI and a ROA?

RPKI is the overall public key infrastructure that ties IP resources to their holders. A ROA is one signed object within it that states which ASN may originate a specific prefix and up to what prefix length.

Is a route without a ROA dropped?

Generally no. A route with no covering ROA is in the NotFound state, and most networks still accept it. Only routes that conflict with an existing ROA (Invalid) are commonly rejected.

How long does it take for a new ROA to take effect?

It depends on how often validators fetch data from the RIR repositories. Expect anywhere from a few minutes to a few hours before most networks see the change, so create the ROA before you announce.

Should I set maxLength to /24 for flexibility?

Usually not. A loose maxLength lets forged more-specific announcements with your ASN appear valid. Set maxLength to the longest prefix you actually announce, and add separate ROAs if you deaggregate.

Need to announce your own ASN and IP block? See Nixcon BGP VDS.Learn more