google/gson · error · MalformedJsonException

String contains non-ASCII characters: ${s} at path ${path}

Error message

String contains non-ASCII characters: ${s} at path ${path}

What it means

JsonTreeReader (Gson's reader over an in-memory JsonElement tree) calls validateAscii() inside nextInt() and nextLong() when the current token is a STRING being coerced to a number. If any character has a code point above 127 (e.g. full-width CJK digits like '123'), Gson throws MalformedJsonException because such strings cannot be reliably parsed as a Java integer. The guard exists because non-ASCII numeric characters would otherwise yield silent, wrong numeric results.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java:431

  }

  private String locationString() {
    return " at path " + getPath();
  }

  /** Returns whether every character of {@code s} is ASCII (code point at most 127). */
  public static boolean isAllAscii(String s) {
    for (int i = 0; i < s.length(); i++) {
      if (s.charAt(i) > 127) {
        return false;
      }
    }
    return true;
  }

  private void validateAscii(String s) throws MalformedJsonException {
    if (!isAllAscii(s)) {
      throw new MalformedJsonException(
          "String contains non-ASCII characters: " + s + locationString());
    }
  }

  /** Creates a {@link NumberFormatException} whose message includes the current path. */
  private NumberFormatException numberFormatException(String message, NumberFormatException cause) {
    NumberFormatException exception = new NumberFormatException(message + locationString());
    exception.initCause(cause);
    return exception;
  }
}

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Normalize the offending string to ASCII before parsing, e.g. java.text.Normalizer.normalize(s, Normalizer.Form.NFKC) to fold full-width digits to ASCII
  2. Write a custom TypeAdapter<Integer>/<Long> (registered via GsonBuilder.registerTypeAdapter) that pre-normalizes the string
  3. Fix the data at its origin to emit ASCII digit characters (0-9)

Example fix

// before - throws on JsonPrimitive("123")
int v = jsonElement.getAsInt();

// after - normalize full-width digits to ASCII first
String s = jsonElement.getAsString();
s = java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFKC);
int v = Integer.parseInt(s);
Defensive patterns

Strategy: validation

Validate before calling

// Before parsing a string token as int/long, verify ASCII
import com.google.gson.internal.bind.JsonTreeReader;

String s = jsonPrimitive.getAsString();
if (!JsonTreeReader.isAllAscii(s)) {
    s = java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFKC);
}
int value = Integer.parseInt(s); // safe now

Try / catch

try {
  int v = gson.fromJson(jsonElement, Integer.class);
} catch (com.google.gson.stream.MalformedJsonException e) {
  // message indicates non-ASCII; normalize source and retry, or fall back
}

Prevention

When it happens

Trigger: Deserializing a JsonElement tree into an int/long field where the JSON value is a string token containing non-ASCII characters; calling nextInt()/nextLong() directly on a JsonReader wrapping a JsonPrimitive string with Unicode digits; data produced by CJK-localized systems emitting full-width numerals.

Common situations: Internationalized data from Japanese/Chinese/Korean locales using full-width digits; copy-paste from office suites that auto-convert ASCII digits to typographic Unicode forms; JSON received from systems that localize number formatting.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/8e3398544d7a3e4f. Report an issue: GitHub.