quarkusio/quarkus · error · IllegalArgumentException
Too many links
Error message
Too many links
What it means
LinkDelegate.parse builds a Link object from a Link header string. The grammar allows exactly one <uri> target; if a second '<' character is encountered after an href has already been parsed, the string contains multiple links, which this parser does not support, so it throws IllegalArgumentException("Too many links").
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/headers/LinkDelegate.java:42
Parser(final String value) {
this.value = value;
builder = new LinkBuilderImpl();
}
public Link getLink() {
return builder.build();
}
public void parse() {
String href = null;
MultivaluedMap<String, String> attributes = new QuarkusMultivaluedHashMap<String, String>();
while (curr < value.length()) {
char c = value.charAt(curr);
if (c == '<') {
if (href != null)
throw new IllegalArgumentException("Too many links");
href = parseLink();
} else if (c == ';' || c == ' ') {
curr++;
continue;
} else {
parseAttribute(attributes);
}
}
populateLink(href, attributes);
}
protected void populateLink(String href, MultivaluedMap<String, String> attributes) {
builder.uri(href);
for (String name : attributes.keySet()) {
List<String> values = attributes.get(name);
if (name.equals("rel")) {
for (String val : values)View on GitHub (pinned to e1c734241f)
Solutions
- Split the header on the link separator and parse each link individually (or use a MultivaluedMap so each Link header is a separate value)
- Parse only the first link via a regex capturing one <...>; rel=... group
- Fix the server/proxy to emit separate Link headers instead of a merged value
- Wrap parse in try-catch if multiple links are expected and handle them by splitting on ',\s*</' boundaries
Example fix
// before
Link link = LinkDelegate.INSTANCE.fromString("</next>; rel=\"next\", </prev>; rel=\"prev\""); // throws
// after
for (String part : headerValue.split(",(?=\s*<)")) {
Link link = LinkDelegate.INSTANCE.fromString(part.trim());
// handle each link
} Defensive patterns
Strategy: try-catch
Validate before calling
long targets = headerValue.chars().filter(c -> c == '<').count();
if (targets > 1) { /* split on commas and parse each link separately */ } Try / catch
try {
Link link = LinkDelegate.INSTANCE.fromString(value);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Too many links")) {
// split value on ",(?=\s*<)" and parse each part
}
} Prevention
- Parse RFC 8288 multi-link headers by splitting before delegating
- Keep Link headers as separate multivalued map entries
- Be aware this parser handles a single link per string only
When it happens
Trigger: Passing a multi-value Link header string like '</page/2>; rel="next", </page/1>; rel="prev"' to LinkDelegate.parse/fromString, or a malformed value containing two <...> targets.
Common situations: REST APIs emitting comma-separated Link headers (pagination per RFC 8288) being parsed with a single-Link parser; concatenated header values from proxies that merge Link headers.
Related errors
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/9780bc6d27d829f8.
Report an issue: GitHub.