alibaba/nacos · error · IllegalArgumentException
{} must be a finite JSON number
Error message
{} must be a finite JSON number What it means
validateJsonValue() rejects a Float extension value that is NaN or ±Infinity (Float.isFinite is false), because those have no valid JSON representation. Only finite floats are allowed.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:179
bytes = JacksonUtils.toJsonBytes(extensions);
} catch (NacosSerializationException e) {
throw new IllegalArgumentException("Unable to serialize Agent extensions", e);
}
if (bytes.length > MAX_EXTENSIONS_SIZE) {
throw new IllegalArgumentException(
"Agent extensions exceeds " + MAX_EXTENSIONS_SIZE + " bytes");
}
}
private static void validateJsonValue(Object value, String fieldName) {
if (value == null || value instanceof String || value instanceof Boolean
|| value instanceof Byte || value instanceof Short || value instanceof Integer
|| value instanceof Long) {
return;
}
if (value instanceof Float) {
if (!Float.isFinite((Float) value)) {
throw new IllegalArgumentException(fieldName + " must be a finite JSON number");
}
return;
}
if (value instanceof Double) {
if (!Double.isFinite((Double) value)) {
throw new IllegalArgumentException(fieldName + " must be a finite JSON number");
}
return;
}
if (value instanceof Number) {
return;
}
if (value instanceof List) {
for (Object item : (List<?>) value) {
validateJsonValue(item, fieldName);
}
return;
}View on GitHub (pinned to 9b989acdf1)
Solutions
- Sanitize float values before inserting into extensions: replace non-finite with null or a sentinel and skip, or use Double and clamp.
- Use Float.isFinite(v) guard and drop/normalize the value if false.
- Store precision-sensitive numbers as strings if you need exact representation.
Example fix
// before
ext.put("ratio", numerator / (float) denominator); // denominator 0 -> Infinity
// after
float r = numerator / (float) denominator;
ext.put("ratio", Float.isFinite(r) ? r : null); Defensive patterns
Strategy: validation
Validate before calling
static Object sanitizeNumber(Object v) {
return (v instanceof Float && !Float.isFinite((Float) v)) ? null : v;
}
// apply before inserting into extensions Type guard
static boolean isFiniteJsonNumber(Object v) {
if (v instanceof Float) return Float.isFinite((Float) v);
if (v instanceof Double) return Double.isFinite((Double) v);
return v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long || v instanceof Number;
} Prevention
- Guard float results with Float.isFinite before insertion.
- Treat division/log inputs defensively against zero/negative.
- Store precision-sensitive values as strings if needed.
When it happens
Trigger: An extensions value is a Float computed from a division by zero, Math operations yielding infinity, or Float.parseFloat("NaN"), then passed into the ext and serialized.
Common situations: Metrics/statistics code writing ratio or score floats into extensions without guarding against infinity; deserialization of a numeric token into Float that overflows.
Related errors
- extensions exceeds 32 entries
- Agent extensions contains a non-string JSON object key
- Unable to serialize Agent extensions
- Agent extensions exceeds {} bytes
- {} contains a non-string JSON object key
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/3fa2166cbcb55c27.
Report an issue: GitHub.