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

  1. Escape the control characters in the string: replace raw newline with \n, tab with \t, etc.
  2. Remove the raw control characters or sanitize/normalize the text before parsing
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/087d4f705251c747. Report an issue: GitHub.