google/gson · error · JsonSyntaxException

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

Error message

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

What it means

Thrown by Gson's UUID TypeAdapter when java.util.UUID.fromString cannot parse the JSON string. UUID.fromString requires the canonical 8-4-4-4-12 hex form (with or without surrounding braces in some JDKs); any deviation throws IllegalArgumentException, which Gson wraps as a JsonSyntaxException with the path.

Source

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

        }
      };

  public static final TypeAdapterFactory INET_ADDRESS_FACTORY =
      newTypeHierarchyFactory(InetAddress.class, INET_ADDRESS);

  public static final TypeAdapter<UUID> UUID =
      new TypeAdapter<UUID>() {
        @Override
        public UUID read(JsonReader in) throws IOException {
          if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
          }
          String s = in.nextString();
          try {
            return java.util.UUID.fromString(s);
          } catch (IllegalArgumentException e) {
            throw new JsonSyntaxException(
                "Failed parsing '" + s + "' as UUID; at path " + in.getPreviousPath(), e);
          }
        }

        @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 {

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Validate and normalize the UUID string before Gson sees it (strip whitespace, insert hyphens for compact forms, lowercase hex).
  2. Fix the upstream producer to emit canonical UUIDs (java.util.UUID.toString or equivalent).
  3. Register a custom TypeAdapter<UUID> that accepts multiple formats (compact, braced, URN "urn:uuid:...") and normalizes before calling UUID.fromString.
  4. If null is meaningful, ensure the producer emits JSON null, not the string "null".

Example fix

// before
public class Order { public UUID id; }
// JSON: {"id":"550e8400e1b841d4a716446655440000"} -> fails (no hyphens)

// after: custom adapter normalizing compact UUIDs
Gson g = new GsonBuilder()
  .registerTypeHierarchyAdapter(UUID.class, new TypeAdapter<UUID>() {
    public UUID read(JsonReader in) throws IOException {
      String s = in.nextString().replace("urn:uuid:","").replace("-","").trim();
      if (s.length() != 32) throw new JsonSyntaxException("bad uuid: "+s);
      String f = s.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5");
      return java.util.UUID.fromString(f);
    }
    public void write(JsonWriter out, UUID v) throws IOException { out.value(v==null?null:v.toString()); }
  }).create();
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern UUID_LIKE =
  Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
String raw = jsonNode.get("id").getAsString();
if (raw != null && !UUID_LIKE.matcher(raw.trim()).matches()) {
  throw new IllegalArgumentException("Not a canonical UUID: " + raw);
}

Try / catch

try {
  return gson.fromJson(json, HasId.class);
} catch (JsonSyntaxException e) {
  if (e.getMessage().contains("as UUID")) {
    // normalize or reject; e.g. strip hyphens and reformat, or drop record
    throw new IllegalArgumentException("Malformed UUID in payload", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a field of type java.util.UUID from a JSON string that is malformed: wrong length, missing hyphens ("550e8400e1b841d4a716446655440000"), containing non-hex characters, extra whitespace, or a value like "null" that is not the JSON null token.

Common situations: Upstream services emitting UUIDs without hyphens or in uppercase with different grouping; copying IDs with leading/trailing spaces; mixing UUID and ULID/ObjectId formats; quoting the literal string "null" instead of emitting JSON null.

Related errors


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