Summary

  • FORT’s default ASPA provider cap is 4,000. At the examined merge, it checks the sum of two current list lengths before deduplicating their union.
  • The over-cap branch returns a null provider pointer and zero count, which the type contract associates with withdrawal. No affected customer, delivered router withdrawal or resource cancellation was observed.

Consider two sorted provider lists for the same customer AS. Each contains 2,500 ASIDs, and their memberships are identical. Their mathematical union contains 2,500 providers. In FORT’s fixed release code, the pair can nevertheless meet a 5,000-entry prospective count before that union is built.

This is a conditional reading of a function, not a discovered pair of live ASPA publications. It assumes the lists have passed the other checks and reach the same customer’s merge. The question is what a limit measures at the point where it is enforced.

LACNIC’s 9 September 2026 introduction to ASPA names FORT among existing implementations. ASPA supplies a customer AS’s authorised provider relationships, rather than merely checking a route’s origin. The implementation question here is narrower than adoption statistics or router protocol negotiation: when overlapping information arrives, which count meets the budget first?

The examined release is 1.7.0.experimental, published on 16 July. Its tag resolves to commit c67d14bcdbc8cbcf100e97c481a8c4ef6eb0ca7e. This September review does not announce a September release or inventory current installations. It did not execute FORT, query production or publish synthetic ASPAs.

A limit with two entrances

The usage guide gives aspa.max-providers a default of 4,000 and a configurable integer range of zero to 16,380. It describes a customer’s declarations across the RPKI trees in each validation cycle and says customers exceeding the count are invalidated. Configuration code separately sets the default and bounds. Those are this implementation’s settings, not a protocol ceiling established by this article. Zero is not presented as an unlimited switch.

The object parser checks a single list first. In parse_providers, a list longer than the configured limit is rejected before allocating its provider array and handing the object onward. Providers within an object must be ascending, cannot repeat, and cannot be the customer itself. An overlap between two otherwise admitted lists is therefore different from a duplicate inside one object. List shape alone does not establish all signed-object and certificate validity.

A second entrance is the database merge. Entries are keyed by customer. When add_aspa replaces an existing same-customer entry, it calls merge_providers. That function initially sets m to old->count plus new->count. If the existing provider pointer is null, or this sum exceeds the configured limit, it returns a null pointer and a zero count.

Only after that guard does it allocate space for the prospective sum and run the sorted-list merge. Cross-list duplicates are removed there. Their smaller union arrives too late to reduce the count used by the guard. add_aspa assigns the result to the newly stored customer entry and releases superseded provider storage. The type header says null and zero are to be withdrawn.

This makes the 2,500-plus-2,500 example straightforward: 5,000 exceeds 4,000 before the identical memberships could reduce the result to 2,500. The arithmetic does not report a real rejected customer or a live network event.

Not a running total of every original entry

There is another distinction worth keeping. The existing count may already be the product of earlier deduplication. It is not necessarily a counter retaining the length of every original object seen in the cycle.

Imagine a healthy single-target sequence of three identical 1,500-ASID lists. The first pair has a prospective count of 3,000, then a deduplicated result of 1,500. Adding the third list produces a prospective count of 3,000 again. The original lists contain 4,500 entries in total, but that particular sequence need not exceed the 4,000 guard.

Again, this is a conditional function sequence, not a guarantee about real tree-processing groups. It separates original-entry totals, current two-input capacity and distinct membership. “Provider count” can refer to different quantities unless its stage is named.

The numeric comparison is strictly greater than the limit. A sum exactly equal to 4,000 does not trigger that numeric branch, though other checks remain. Nor does every null result prove an exceeded cap: the existing-null condition is separate. This review does not audit all merge orders or claim every invalid marker is permanently sticky.

A defensible budget needs a unit

The timing is consistent with a defensive allocation budget: the next allocation uses the summed input length. Checking before allocation can constrain intermediate capacity, even when deduplication would produce fewer members. That is an inference from structure, not a maintainer’s stated intention or a measured performance result. It is not enough to pronounce the guard a bug.

For an operator counting the final set, however, distinct membership is the obvious unit. A useful clarification would say which budget is being protected at the merge: intermediate two-input capacity or final unique providers. Clarifying documentation and changing the ordering are different choices. Neither is reported as adopted, and this article does not recommend simply increasing the limit.

The downstream claim needs equal restraint. A null result and a withdrawal convention do not prove what a router session received, what policy it applied or whether traffic changed. A cache’s treatment of provider information does not cancel the customer’s ASN or resource registration. The finding concerns admission to a software result, not an incident notification.

Sources

  1. LACNIC’s ASPA introduction
  2. FORT 1.7.0.experimental release
  3. Fixed-commit parameter guide
  4. ASPA provider-object parsing
  5. Customer-entry merge and counting order
  6. Configuration defaults and bounds
  7. Provider type and withdrawal convention