{"record":{"id":"482767058871fa50","repo":"quarkusio/quarkus","slug":"no-end-to-link","errorCode":null,"errorMessage":"No end to link","messagePattern":"No end to link","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":81,"sourceCode":"                    for (String val : values)\n                        builder.title(val);\n\n                } else if (name.equals(\"type\")) {\n                    for (String val : values)\n                        builder.type(val);\n\n                } else {\n                    for (String val : values)\n                        builder.param(name, val);\n\n                }\n            }\n        }\n\n        public String parseLink() {\n            int end = value.indexOf('>', curr);\n            if (end == -1)\n                throw new IllegalArgumentException(\"No end to link\");\n            String href = value.substring(curr + 1, end);\n            curr = end + 1;\n            return href;\n        }\n\n        public void parseAttribute(MultivaluedMap<String, String> attributes) {\n            int end = value.indexOf('=', curr);\n            if (end == -1 || end + 1 >= value.length())\n                throw new IllegalArgumentException(\"No end to parameter\");\n            String name = value.substring(curr, end);\n            name = name.trim();\n            curr = end + 1;\n            String val = null;\n            if (curr >= value.length()) {\n                val = \"\";\n            } else {\n\n                if (value.charAt(curr) == '\"') {","sourceCodeStart":63,"sourceCodeEnd":99,"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#L63-L99","documentation":"Inside LinkDelegate parsing, parseLink extracts the target URI between '<' and '>'. If no closing '>' exists anywhere after the current position (indexOf returns -1), the header string is truncated or malformed, so it throws IllegalArgumentException(\"No end to link\").","triggerScenarios":"Parsing a Link header value with an unterminated target, e.g. '</page/2; rel=\"next\"' (missing '>'), passed to LinkDelegate.parse/fromString.","commonSituations":"Truncated headers from proxies/log processing; hand-written header strings missing the closing angle bracket; copy-paste errors when constructing Link headers in tests.","solutions":["Fix the header string so the target URI is enclosed: '<uri>; rel=\"...\"'","Validate the presence of '<' and '>' before calling parse","Check the origin of the truncated value (proxy, log reassembly, manual concatenation)","Catch IllegalArgumentException and log the raw value for diagnosis"],"exampleFix":"// before\nLink link = LinkDelegate.INSTANCE.fromString(\"</page/2; rel=\\\"next\\\"\"); // missing '>'\n// after\nLink link = LinkDelegate.INSTANCE.fromString(\"</page/2>; rel=\\\"next\\\"\");","handlingStrategy":"validation","validationCode":"int open = value.indexOf('<'); int close = value.indexOf('>');\nif (open == -1 || close == -1 || close < open) { throw new IllegalArgumentException(\"Malformed Link header (missing '>'): \" + value); }","typeGuard":null,"tryCatchPattern":"try {\n    Link link = LinkDelegate.INSTANCE.fromString(value);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"No end to link\")) {\n        // log raw value; header was truncated or malformed\n    }\n}","preventionTips":["Verify '<uri>' pairing in Link header strings before parsing","Check for truncation when headers pass through proxies/log tooling","Add unit tests for Link header construction to catch missing brackets"],"tags":["jaxrs","http-headers","link-header","parsing","malformed-header"],"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"}