{"record":{"id":"9780bc6d27d829f8","repo":"quarkusio/quarkus","slug":"too-many-links","errorCode":null,"errorMessage":"Too many links","messagePattern":"Too many links","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/headers/LinkDelegate.java","lineNumber":42,"sourceCode":"\n        Parser(final String value) {\n            this.value = value;\n            builder = new LinkBuilderImpl();\n        }\n\n        public Link getLink() {\n            return builder.build();\n        }\n\n        public void parse() {\n            String href = null;\n            MultivaluedMap<String, String> attributes = new QuarkusMultivaluedHashMap<String, String>();\n            while (curr < value.length()) {\n\n                char c = value.charAt(curr);\n                if (c == '<') {\n                    if (href != null)\n                        throw new IllegalArgumentException(\"Too many links\");\n                    href = parseLink();\n                } else if (c == ';' || c == ' ') {\n                    curr++;\n                    continue;\n                } else {\n                    parseAttribute(attributes);\n                }\n            }\n            populateLink(href, attributes);\n\n        }\n\n        protected void populateLink(String href, MultivaluedMap<String, String> attributes) {\n            builder.uri(href);\n            for (String name : attributes.keySet()) {\n                List<String> values = attributes.get(name);\n                if (name.equals(\"rel\")) {\n                    for (String val : values)","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/headers/LinkDelegate.java#L24-L60","documentation":"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\").","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nLink link = LinkDelegate.INSTANCE.fromString(\"</next>; rel=\\\"next\\\", </prev>; rel=\\\"prev\\\"\"); // throws\n// after\nfor (String part : headerValue.split(\",(?=\\s*<)\")) {\n    Link link = LinkDelegate.INSTANCE.fromString(part.trim());\n    // handle each link\n}","handlingStrategy":"try-catch","validationCode":"long targets = headerValue.chars().filter(c -> c == '<').count();\nif (targets > 1) { /* split on commas and parse each link separately */ }","typeGuard":null,"tryCatchPattern":"try {\n    Link link = LinkDelegate.INSTANCE.fromString(value);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"Too many links\")) {\n        // split value on \",(?=\\s*<)\" and parse each part\n    }\n}","preventionTips":["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"],"tags":["jaxrs","http-headers","link-header","rfc8288","parsing"],"backgroundTag":"malformed-link-header","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}