quarkusio/quarkus · error · IllegalArgumentException

String not closed

Error message

String not closed

What it means

readString() consumes characters until it finds the closing double quote. If the loop ends because the end of the input text was reached without seeing '"', the string literal was never terminated, and the parser throws this IllegalArgumentException. It signals an unterminated JSON string.

Source

Thrown at core/builder/src/main/java/io/quarkus/builder/JsonReader.java:242

                    case '/': // solidus
                    case 'b': // backspace
                    case 'f': // formfeed
                    case 'n': // linefeed
                    case 'r': // carriage return
                    case 't': // horizontal tab
                        break;
                    case 'u': // unicode
                        if (unicodeString == null) {
                            unicodeString = new StringBuilder(position - start);
                        }
                        unicodeString.append(text, start, position - 1);
                        unicodeString.append(readUnicode());
                        start = position;
                }
            }
        }

        throw new IllegalArgumentException("String not closed");
    }

    private char readUnicode() {
        final char digit1 = Character.forDigit(nextChar(), 16);
        final char digit2 = Character.forDigit(nextChar(), 16);
        final char digit3 = Character.forDigit(nextChar(), 16);
        final char digit4 = Character.forDigit(nextChar(), 16);
        return (char) (digit1 << 12 | digit2 << 8 | digit3 << 4 | digit4);
    }

    /**
     * number
     * |---- integer fraction exponent
     */
    private JsonValue readNumber(int numStartIndex) {
        final boolean isFraction = skipToEndOfNumber();
        final String number = text.substring(numStartIndex, position);
        return isFraction

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add the missing closing double quote to the string literal.
  2. Escape any inner double quotes with backslash (\") so they do not terminate the string early.
  3. Validate the JSON with a standard parser before use to locate the unterminated string.
  4. Verify the input source was not truncated (file write completed, payload fully received).

Example fix

// before
String json = "{\"name\":\"quarkus}"; // value string never closed

// after
String json = "{\"name\":\"quarkus\"}";
Defensive patterns

Strategy: validation

Validate before calling

boolean stringsClosed(String json) {
    int count = 0;
    for (int i = 0; i < json.length(); i++) {
        if (json.charAt(i) == '"' && (i == 0 || json.charAt(i - 1) != '\\')) count++;
    }
    return count % 2 == 0;
}
// call before parsing: if (!stringsClosed(input)) throw new IllegalArgumentException("unterminated string");

Try / catch

try {
    JsonReader.parse(json);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("String not closed")) {
        throw new ConfigException("Unterminated JSON string literal; add the missing closing quote or escape inner quotes", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Parsing JSON where a string value starts with '"' but the input ends before the closing quote, e.g. "{\"name\":\"quarkus}" or a truncated document; also when an unescaped '"' earlier inside the string prematurely closed it and left the real terminator orphaned.

Common situations: Truncated JSON files or network payloads; hand-written JSON missing a quote; strings containing unescaped inner quotes like "{\"say\":\"hi \"there\""; generated JSON cut off by a length limit or build-time error.

Related errors


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