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 isFractionView on GitHub (pinned to e1c734241f)
Solutions
- Add the missing closing double quote to the string literal.
- Escape any inner double quotes with backslash (\") so they do not terminate the string early.
- Validate the JSON with a standard parser before use to locate the unterminated string.
- 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
- Escape inner double quotes as \" inside JSON string values
- Check that input files/payloads were not truncated before parsing
- Prefer a serializer library over manual JSON construction
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
- Json array ended without ]
- Unable to read json constant for: %s
- Control characters not allowed in json string
- Unable to fully read json value
- Unknown start character for json value: ${ch}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c9bd1a3f14dca758.
Report an issue: GitHub.