google/gson · error · JsonSyntaxException

Failed parsing '${s}' as Currency; at path ${path}

Error message

Failed parsing '${s}' as Currency; at path ${path}

What it means

Thrown by Gson's Currency TypeAdapter when java.util.Currency.getInstance cannot resolve the JSON string as an ISO 4217 currency code. Currency.getInstance throws IllegalArgumentException for unknown codes, which Gson wraps as a JsonSyntaxException. Note this adapter is nullSafe but does NOT consume a JSON null token explicitly in nextString().

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:815

        }

        @Override
        public void write(JsonWriter out, UUID value) throws IOException {
          out.value(value == null ? null : value.toString());
        }
      };

  public static final TypeAdapterFactory UUID_FACTORY = newFactory(UUID.class, UUID);

  public static final TypeAdapter<Currency> CURRENCY =
      new TypeAdapter<Currency>() {
        @Override
        public Currency read(JsonReader in) throws IOException {
          String s = in.nextString();
          try {
            return Currency.getInstance(s);
          } catch (IllegalArgumentException e) {
            throw new JsonSyntaxException(
                "Failed parsing '" + s + "' as Currency; at path " + in.getPreviousPath(), e);
          }
        }

        @Override
        public void write(JsonWriter out, Currency value) throws IOException {
          out.value(value.getCurrencyCode());
        }
      }.nullSafe();
  public static final TypeAdapterFactory CURRENCY_FACTORY = newFactory(Currency.class, CURRENCY);

  /**
   * An abstract {@link TypeAdapter} for classes whose JSON serialization consists of a fixed set of
   * integer fields. That is the case for {@link Calendar} and the legacy serialization of various
   * {@code java.time} types.
   */
  abstract static class IntegerFieldsTypeAdapter<T> extends TypeAdapter<T> {
    private final List<String> fields;

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Ensure the JSON value is an uppercase ISO 4217 code (e.g. "USD", "EUR").
  2. Update the JDK / currency table (JDK holds the list in <jdk>/lib/currency.data) or run on a current JDK release so newer codes are recognized.
  3. Register a custom TypeAdapter<Currency> that uppercases the input and maps known aliases/symbols to Currency.getInstance codes.
  4. If only the symbol is available, deserialize as String and resolve through a lookup table in your domain code.

Example fix

// before
public class Price { public Currency currency; }
// JSON: {"currency":"usd"} -> fails (lowercase)

// after: normalize case with a custom adapter
Gson g = new GsonBuilder()
  .registerTypeHierarchyAdapter(Currency.class, new TypeAdapter<Currency>() {
    public Currency read(JsonReader in) throws IOException {
      String s = in.nextString().trim().toUpperCase(Locale.ROOT);
      return Currency.getInstance(s);
    }
    public void write(JsonWriter out, Currency v) throws IOException { out.value(v.getCurrencyCode()); }
  }).create();
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> ISO4217 =
  Set.of("USD","EUR","GBP","JPY","CHF","CAD","AUD","CNY","INR","BRL","MXN"); // extend as needed
String raw = jsonNode.get("currency").getAsString();
if (raw == null || !ISO4217.contains(raw.trim().toUpperCase(Locale.ROOT))) {
  throw new IllegalArgumentException("Unsupported currency code: " + raw);
}
// or rely on Currency.getAvailableCurrencies() at startup

Try / catch

try {
  return gson.fromJson(json, Price.class);
} catch (JsonSyntaxException e) {
  if (e.getMessage().contains("as Currency")) {
    throw new IllegalArgumentException("Unknown currency code", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a field of type java.util.Currency from a JSON string that is not a valid ISO 4217 code: lowercase ("usd" instead of "USD"), a 3-letter code not in the JDK's currency list, a currency symbol like "$", or a numeric code as a string.

Common situations: Mixing currency symbols ($) with ISO codes; receiving locale-formatted currency; new or unofficial ISO 4217 codes not yet in the running JDK's currency list; case-sensitive data sources emitting lowercase codes.

Related errors


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