quarkusio/quarkus · error · IllegalArgumentException

Unknown start character for json value: ${ch}

Error message

Unknown start character for json value: ${ch}

What it means

readValue() dispatches on the first character of a JSON value ('{', '[', '"', digits, '-', 't', 'f', 'n'). If the character matches none of these, the input is not valid JSON at that position and the reader throws IllegalArgumentException including the offending character code. This usually means stray characters or structural mistakes in the JSON text.

Source

Thrown at independent-projects/bootstrap/json/src/main/java/io/quarkus/bootstrap/json/JsonReader.java:76

        switch (ch) {
            case '{':
                return readObject();
            case '[':
                return readArray();
            case '"':
                return readString();
            case 't':
                return readConstant("true", JsonBoolean.TRUE);
            case 'f':
                return readConstant("false", JsonBoolean.FALSE);
            case 'n':
                return readConstant("null", JsonNull.INSTANCE);
            default:
                if (Character.isDigit(ch) || '-' == ch) {
                    return readNumber(position);
                }
                throw new IllegalArgumentException("Unknown start character for json value: " + ch);
        }
    }

    /**
     * object
     * |---- '{' ws '}'
     * |---- '{' members '}'
     * </p>
     * members
     * |----- member
     * |----- member ',' members
     */
    private JsonValue readObject() {
        position++;

        Map<JsonString, JsonValue> members = new HashMap<>();

        while (position < length) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Validate the JSON with a linter/validator and fix the character at the reported position
  2. Quote strings with double quotes only; remove stray commas or characters before parsing
  3. Confirm the response/content is actually JSON (check Content-Type) before parsing

Example fix

// before
reader.parse("{name: 'x'}"); // single quotes, unquoted key
// after
reader.parse("{\"name\": \"x\"}");
Defensive patterns

Strategy: validation

Validate before calling

// Cheap pre-check for an obviously non-JSON first character
char first = jsonText.stripLeading().charAt(0);
if (first != '{' && first != '[') {
    throw new IllegalArgumentException("Input does not look like JSON, starts with: " + first);
}

Try / catch

try {
    JsonValue v = new JsonReader(text).read();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unknown start character")) {
        // inspect the character code in the message; fix or reject the input
    }
}

Prevention

When it happens

Trigger: Input contains an unexpected character where a value should start, e.g. an unquoted word, a single-quoted string ('...'), a trailing comma followed by '}', or garbage bytes after a top-level value.

Common situations: Hand-written JSON with unquoted keys/values or single quotes; concatenating two JSON documents; responses from a non-JSON endpoint (HTML error pages) being fed to the parser.

Related errors


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