{"id":"a8878177b85c9e5e","repo":"google/gson","slug":"value-is-not-a-valid-double-value-as-per-json","errorCode":null,"errorMessage":"value + \" is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.\"","messagePattern":"value \\+ \" is not a valid double value as per JSON specification\\. To override this behavior, use GsonBuilder\\.serializeSpecialFloatingPointValues\\(\\) method\\.\"","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java","lineNumber":519,"sourceCode":"    }\n\n    @Override\n    public void write(JsonWriter out, Number value) throws IOException {\n      if (value == null) {\n        out.nullValue();\n        return;\n      }\n      double doubleValue = value.doubleValue();\n      if (strict) {\n        checkValidFloatingPoint(doubleValue);\n      }\n      out.value(doubleValue);\n    }\n  }\n\n  private static void checkValidFloatingPoint(double value) {\n    if (Double.isNaN(value) || Double.isInfinite(value)) {\n      throw new IllegalArgumentException(\n          value\n              + \" is not a valid double value as per JSON specification. To override this\"\n              + \" behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.\");\n    }\n  }\n\n  public static final TypeAdapter<Number> FLOAT = new FloatAdapter(false);\n  public static final TypeAdapter<Number> FLOAT_STRICT = new FloatAdapter(true);\n\n  public static final TypeAdapter<Number> DOUBLE = new DoubleAdapter(false);\n  public static final TypeAdapter<Number> DOUBLE_STRICT = new DoubleAdapter(true);\n\n  public static final TypeAdapter<Character> CHARACTER =\n      new TypeAdapter<Character>() {\n        @Override\n        public Character read(JsonReader in) throws IOException {\n          if (in.peek() == JsonToken.NULL) {\n            in.nextNull();","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L501-L537","documentation":"checkValidFloatingPoint throws IllegalArgumentException when a double or float being serialized is NaN or +/- Infinity, because the JSON specification does not permit these tokens. The default FLOAT/DOUBLE adapters are 'strict' and call this check on write; to emit non-finite values you must opt in via GsonBuilder.serializeSpecialFloatingPointValues().","triggerScenarios":"Serializing an object whose double/float field holds NaN or Infinity (e.g., result of 0.0/0.0, 1.0/0.0, overflow) using the default Gson FLOAT_STRICT/DOUBLE_STRICT adapter. Triggered at line 519 inside the adapter write path.","commonSituations":"Math/financial computations producing NaN/Infinity; division-by-zero results; sensor/statistical aggregates; unit tests with degenerate values; migrating from Jackson which may emit these as strings by default.","solutions":["Enable non-finite serialization: new GsonBuilder().serializeSpecialFloatingPointValues().create().","Sanitize the value before serialization (replace NaN/Infinity with null or a sentinel).","Register a custom TypeAdapter<Double> that writes NaN/Infinity as a string token.","Guard computations that can produce NaN/Infinity at the source."],"exampleFix":"// before\nGson gson = new Gson();\ngson.toJson(new Stats(Double.POSITIVE_INFINITY, Double.NaN)); // throws\n\n// after\nGson gson = new GsonBuilder()\n    .serializeSpecialFloatingPointValues()\n    .create();\ngson.toJson(new Stats(Double.POSITIVE_INFINITY, Double.NaN));","handlingStrategy":"validation","validationCode":"// Reject NaN/Infinity before serializing, or decide to allow them\nfor (Field f : Stats.class.getDeclaredFields()) {\n  if ((f.getType()==double.class||f.getType()==Double.class) && !gsonAllowsSpecial()) {\n    double d = f.getDouble(obj);\n    if (Double.isNaN(d)||Double.isInfinite(d)) throw new IllegalStateException(\"Non-finite: \"+f);\n  }\n}","typeGuard":"// Guard values before they reach Gson\nstatic boolean isSerializableDouble(double d, boolean allowSpecial) {\n  return allowSpecial || (!Double.isNaN(d) && !Double.isInfinite(d));\n}","tryCatchPattern":"try {\n  gson.toJson(stats);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"is not a valid double value as per JSON specification\")) {\n    // rebuild gson with serializeSpecialFloatingPointValues, or sanitize\n    gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();\n  } else throw e;\n}","preventionTips":["Enable serializeSpecialFloatingPointValues once if your domain legitimately produces NaN/Infinity.","Sanitize computed doubles before placing them on serializable objects.","Unit-test serialization with extreme math inputs."],"tags":["gson","serialization","double","float","nan","infinity"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}