Summary

  • Barry’s README lists ::/0 as the default IPv6 resource for a trust anchor, while open issue 7 reports that the Repository Descriptor parser rejects that spelling in certificate and ROA resource fields.
  • The commit-pinned lexer can continue a token containing colons and a slash, but it will start an unquoted token only with an alphanumeric character, $ or . A leading colon therefore fails before Barry’s IP-prefix parser runs.
  • RFC 4291 makes ::/0 a legitimate IPv6 prefix and RFC 5952 makes it the canonical rendering. 0::/0 denotes the same prefix, but is not the maximally compressed output form.
  • No source establishes that Barry emitted an invalid object, that a relying party saw one, or that LACNIC production or routing was affected. The useful repair is a versioned lexer-to-DER conformance table with stage-coded failures.

Two colons, then one zero

Place the two strings on separate lines and the defect is almost too small to see:

::/0
0::/0

They denote the same IPv6 /0: the all-zero address with a zero-length prefix. Yet the public record around issue 7 in LACNIC’s Barry repository says the first spelling is rejected and the second works around the rejection. The difference is not network authority, prefix scope or DER meaning. It is whether a text lexer agrees to begin a token.

That distinction matters because Barry is a tool for manufacturing RPKI material, including deliberately bad material for testing. Before such a generator can exercise a relying party’s rejection logic, it needs a trustworthy positive path from legitimate source text to an exact semantic value. If the source language refuses a canonical spelling, a later “failure” cannot be assigned to certificate validation. The object was never made.

The strongest institutional reading should come first. Barry’s repository metadata describes a small generator, not a production service. The commit-pinned README calls both the project and its Repository Descriptor specification work in progress and warns that incompatible changes may happen before 1.0. The captured release and tag lists are empty. An open defect with a compact example is therefore evidence of transparent prototyping, not evidence of operational damage.

What the issue shows—and what it does not

Issue 7 was opened on 28 August 2026. At the 6 September evidence cutoff it remained open, with no labels, comments or later update. GitHub records the reporter’s association as NONE. There is no maintainer reply confirming reproduction, diagnosis or intended behaviour.

The report places ::/0 in two descriptor locations: the IP resource extension of a CA certificate and the ipAddrBlocks of a ROA. It proposes 0::/0 as the current workaround. There is a useful wrinkle in the evidence. The displayed reproduction uses ::/0 in both locations, but the pasted trace is not a byte-for-byte transcript of that displayed descriptor. Its first printed value is already 0::/0; the trace later stops when the second field begins with a colon and reports Unexpected character: : (0x3a).

That mismatch does not erase the issue. It narrows what a careful account can say. The trace visibly demonstrates a leading-colon failure in one shown path. The reporter states that the canonical form fails in both named fields. The public evidence does not independently demonstrate two byte-identical failures in a single run. A conformance record should preserve the exact submitted bytes precisely because copying a workaround into one field can silently change the experiment.

Nor does the issue show a malformed certificate or ROA. It does not show a repository being published, a validator processing an object, a route changing or LACNIC’s production RPKI system being involved. Those events sit downstream of the observed boundary and remain unsupported.

The lexer explains the asymmetry

The captured repository points to main commit 994a598321336baf1767f0fbfb460ed96c29fe4f, dated 1 September. Its subject concerns AKI authorityCertIssuer; it does not claim to address issue 7. The recent-commit listing supplies context, not proof that this particular behaviour was introduced or fixed by a named change.

At that commit, the boundary is readable in src/rpki_tree.c. next_token starts an unquoted string only when the first character is alphanumeric, a dollar sign or a hyphen. A colon is none of those. It falls through to try_emoji; an ordinary colon is then rejected as unexpected.

Once an unquoted string has begun, however, the continuation rule permits colons and slashes. It excludes whitespace and the descriptor’s structural separators rather than requiring every character to be alphanumeric. That explains the one-zero workaround without asking an IPv6 library to behave differently. The 0 satisfies the start rule; the following ::/0 remains inside the token.

Barry’s own README makes the boundary sharper. It contains a compressed address such as 2001:db8::/64, which begins with a hexadecimal digit and therefore clears the initial-character gate. It also lists ::/0 as the trust anchor’s default IPv6 resource. The documented default begins with exactly the character the lexer does not admit. “Compressed IPv6 is supported” would therefore be too broad a claim: compression after a leading digit and compression at the beginning take different lexical paths.

The downstream parse_ip_node implementation in src/field.c is not the observed rejector. It splits the text at /, treats a colon as the IPv6 signal, calls inet_pton, and then parses the prefix length. The canonical input that fails at tokenisation never reaches these operations. Calling this an inet_pton problem, a prefix-length failure or a field-binding error would put authority at the wrong stage.

Canonical text is the ordinary case

RFC 4291 permits :: to compress contiguous zero groups and identifies :: as the unspecified all-zero IPv6 address. Its prefix notation is an IPv6 address followed by / and the prefix length, using any of the legitimate address forms. ::/0 is consequently valid IPv6 prefix text.

RFC 5952 separates what implementations accept from what they emit. Implementations must accept legitimate RFC 4291 forms, while generated text should use the canonical representation. Maximum compression removes the visible zero group, making ::/0 the canonical spelling. 0::/0 reaches the same numeric address and prefix length, but it is not the preferred rendered result.

A bounded local check with Ruby’s IPAddr library accepted ::/0, 0::/0, 0000::/0 and the fully written all-zero address as the same range. That check is only supporting evidence about semantic equivalence. It is not a run of Barry and it does not outrank the RFCs.

The final object layer is different again. RFC 3779 represents IP resources in DER as BIT STRING values. Its all-address-block case encodes the zero-length prefix as 03 01 00: a BIT STRING with an unused-bits octet and no address bits. The spelling used in a descriptor does not survive into that value. If both legitimate spellings successfully reach encoding, their source lexemes should converge. If one stops at the lexer, there is no DER value to compare and no relying-party verdict to report.

A small conformance table is enough

The repair need not begin with a broad parser programme. A versioned table can expose the whole control surface. Each row should bind the exact descriptor bytes and their hash, the target field, whether tokenisation accepted the value, the normalized address family, numeric address and prefix length, the canonical rendered string, the Barry commit, and the object hash if construction succeeded.

The terminal stage should come from a controlled list: descriptor-tokenize, prefix-parse, field-bind, object-build, DER-encode or RP-validate. That label prevents a generator-stage refusal from being counted as a validator test. It also makes partial progress visible: a case can pass tokenisation and fail prefix parsing without being confused with one that reached DER.

One invariant gives the table teeth: parse(format(parse(input))) must preserve the same address-family, value and prefix-length tuple. Equivalent legitimate inputs should converge on the same DER prefix value whenever object generation succeeds. The formatter should emit one canonical spelling, while the parser accepts the legitimate input family.

This is narrower than Barry’s broader purpose and narrower than a general RPKI test oracle. It says only what happened at each boundary. That restraint is the value. A negative-test generator can create intentionally invalid objects only after its positive language contract is deterministic enough to prove which object, if any, it created.

Sources