eclipse-vertx/vert.x · error · IllegalArgumentException
only ' ' and '\t' are allowed after '\n': <seq>
Error message
only ' ' and '\t' are allowed after '\n': <seq>
What it means
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.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java:771
return NO_CR_LF_STATE;
}
}
private static int validateCrLfChar(CharSequence seq, int state, char ch) {
switch (state) {
case CR_STATE:
if (ch == '\n') {
return LF_STATE;
}
throw new IllegalArgumentException("only '\\n' is allowed after '\\r': " + seq);
case LF_STATE:
switch (ch) {
case '\t':
case ' ':
// return to the normal state
return NO_CR_LF_STATE;
default:
throw new IllegalArgumentException("only ' ' and '\\t' are allowed after '\\n': " + seq);
}
default:
// this should never happen
throw new AssertionError();
}
}
private static void validateNonPrintableCtrlChar(CharSequence seq, int ch) {
// The only characters allowed in the range 0x00-0x1F are : HTAB, LF and CR
switch (ch) {
case 0x09: // Horizontal tab - HTAB
case 0x0a: // Line feed - LF
case 0x0d: // Carriage return - CR
break;
default:
throw new IllegalArgumentException("a header value contains a prohibited character '" + (int) ch + "': " + seq);
}
}View on GitHub (pinned to fb308bd8c3)
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.
Example fix
// before
request.putHeader("X-List", "a\nb"); // throws
// after
request.putHeader("X-List", "a\r\n b"); // valid obs-fold, or use two headers Defensive patterns
Strategy: validation
Validate before calling
public static boolean isSafeHeaderValue(String v) {
int i = v.indexOf('\n');
while (i >= 0) {
char next = i + 1 < v.length() ? v.charAt(i + 1) : 0;
if (next != ' ' && next != '\t') return false;
i = v.indexOf('\n', i + 1);
}
return true;
} Try / catch
try {
request.putHeader(name, value);
} catch (IllegalArgumentException e) {
throw new BadRequestException("Invalid header value for " + name + ": folded LF not followed by SP/HTAB");
} Prevention
- 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'
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- only '\n' is allowed after '\r': <seq>
- a header value contains a prohibited character '127': <value
- a header value must not end with '\r' or '\n':<seq>
- a header value contains a prohibited character '127': <seq>
- a header value contains a prohibited character '<charCode>':
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/28c2e84bc047e5ad.
Report an issue: GitHub.