{"record":{"id":"28c2e84bc047e5ad","repo":"eclipse-vertx/vert.x","slug":"only-and-t-are-allowed-after-n-seq","errorCode":null,"errorMessage":"only ' ' and '\\t' are allowed after '\\n': <seq>","messagePattern":"only ' ' and '\\\\t' are allowed after '\\\\n': <seq>","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java","lineNumber":771,"sourceCode":"      return NO_CR_LF_STATE;\n    }\n  }\n\n  private static int validateCrLfChar(CharSequence seq, int state, char ch) {\n    switch (state) {\n      case CR_STATE:\n        if (ch == '\\n') {\n          return LF_STATE;\n        }\n        throw new IllegalArgumentException(\"only '\\\\n' is allowed after '\\\\r': \" + seq);\n      case LF_STATE:\n        switch (ch) {\n          case '\\t':\n          case ' ':\n            // return to the normal state\n            return NO_CR_LF_STATE;\n          default:\n            throw new IllegalArgumentException(\"only ' ' and '\\\\t' are allowed after '\\\\n': \" + seq);\n        }\n      default:\n        // this should never happen\n        throw new AssertionError();\n    }\n  }\n\n  private static void validateNonPrintableCtrlChar(CharSequence seq, int ch) {\n    // The only characters allowed in the range 0x00-0x1F are : HTAB, LF and CR\n    switch (ch) {\n      case 0x09: // Horizontal tab - HTAB\n      case 0x0a: // Line feed - LF\n      case 0x0d: // Carriage return - CR\n        break;\n      default:\n        throw new IllegalArgumentException(\"a header value contains a prohibited character '\" + (int) ch + \"': \" + seq);\n    }\n  }","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java#L753-L789","documentation":"Vert.x rejects header values where a line feed ('\\n') is followed by any character other than a space or horizontal tab. HTTP obs-fold (line continuation) requires the pattern CRLF followed by SP/HTAB; an LF followed by other content would be interpreted as a new header line, so this is rejected to prevent header smuggling.","triggerScenarios":"Setting a header value (putHeader/set/HttpHeaders.set) whose value contains \"\\n\" not followed by ' ' or '\\t', e.g. \"a\\nb\" or \"a\\n\\r\"; the exception is thrown from HttpUtils.validateCrLfChar during header validation.","commonSituations":"Building multi-line header values with plain '\\n' separators (e.g. Set-Cookie lists, folded text) without the required trailing space/tab continuation; concatenating body or log fragments containing newlines into a header.","solutions":["Use exactly \"\\r\\n \" (CRLF + space) or \"\\r\\n\\t\" for any folded line inside the header value.","Prefer sending multiple separate headers instead of embedding newlines in one value.","Sanitize with value.replaceAll(\"[\\\\r\\\\n]+\", \" \") before setting the header."],"exampleFix":"// before\nrequest.putHeader(\"X-List\", \"a\\nb\"); // throws\n// after\nrequest.putHeader(\"X-List\", \"a\\r\\n b\"); // valid obs-fold, or use two headers","handlingStrategy":"validation","validationCode":"public static boolean isSafeHeaderValue(String v) {\n  int i = v.indexOf('\\n');\n  while (i >= 0) {\n    char next = i + 1 < v.length() ? v.charAt(i + 1) : 0;\n    if (next != ' ' && next != '\\t') return false;\n    i = v.indexOf('\\n', i + 1);\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  request.putHeader(name, value);\n} catch (IllegalArgumentException e) {\n  throw new BadRequestException(\"Invalid header value for \" + name + \": folded LF not followed by SP/HTAB\");\n}","preventionTips":["Only use the exact obs-fold form \"\\r\\n \" or \"\\r\\n\\t\" when folding lines","Prefer multiple headers over embedded newlines","Unit-test header-building code with inputs containing '\\n'"],"tags":["http","headers","validation","vertx"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}