quarkusio/quarkus · error · IllegalArgumentException
Control characters not allowed in json string
Error message
Control characters not allowed in json string
What it means
JSON strings may not contain raw control characters (ISO control characters, e.g. newline, tab) — they must be escaped as \n, \t, etc. readString() enforces this and throws IllegalArgumentException when it encounters an unescaped control character inside a string literal.
Source
Thrown at independent-projects/bootstrap/json/src/main/java/io/quarkus/bootstrap/json/JsonReader.java:195
* |----- 'r'
* |----- 't'
* |----- 'u' hex hex hex hex
*/
private JsonString readString() {
position++;
int start = position;
// Substring on string values that contain unicode characters won't work,
// because there are more characters read than actual characters represented.
// Use StringBuilder to buffer any string read up to unicode,
// then add unicode values into it and continue as usual.
StringBuilder unescapedValue = null;
while (position < length) {
final int ch = nextChar();
if (Character.isISOControl(ch)) {
throw new IllegalArgumentException("Control characters not allowed in json string");
}
if ('"' == ch) {
final String value;
if (unescapedValue == null) {
value = text.substring(start, position - 1);
} else {
value = unescapedValue.toString();
}
// End of string
return new JsonString(value);
}
if ('\\' == ch) {
if (unescapedValue == null) {
unescapedValue = new StringBuilder().append(text, start, position - 1);
}
final int escaped = nextChar();View on GitHub (pinned to e1c734241f)
Solutions
- Escape the control characters in the string: replace raw newline with \n, tab with \t, etc.
- Remove the raw control characters or sanitize/normalize the text before parsing
- Produce the JSON with a serializer that escapes control characters automatically instead of hand-writing it
Example fix
// before
{"text":"line1
line2"}
// after
{"text":"line1\nline2"} Defensive patterns
Strategy: validation
Validate before calling
String sanitize(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isISOControl(c)) {
sb.append(String.format("\\u%04x", (int) c));
} else {
sb.append(c);
}
}
return sb.toString();
}
// apply sanitize to any text embedded in JSON strings before parsing/serializing Try / catch
try {
JsonValue v = new JsonReader(text).read();
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Control characters not allowed in json string")) {
// re-run with escaped control chars or reject the input
}
} Prevention
- Escape newlines/tabs as \n, \t inside JSON strings — never embed raw control bytes
- Use a serializer to produce JSON from untrusted text instead of hand-writing
- Strip or normalize control characters in ingested text before embedding it in JSON
When it happens
Trigger: A JSON string contains a literal newline, tab, or other control byte instead of its escaped form, e.g. "line1 line2" written with a real newline inside the quotes.
Common situations: Hand-pasting multi-line text into a JSON string; log files or terminal output embedded raw in JSON; data coming from a source that doesn't escape control bytes.
Related errors
- Control characters not allowed in json string
- Json array ended without ]
- String not closed
- Unable to read json constant for: %s
- Unable to fully read json value
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/087d4f705251c747.
Report an issue: GitHub.