alibaba/nacos · error · IllegalArgumentException
Unable to serialize Agent extensions
Error message
Unable to serialize Agent extensions
What it means
validateExtensions() re-serializes the extensions map with JacksonUtils.toJsonBytes to measure its on-wire size; if that serialization throws NacosSerializationException the ext is rejected as 'Unable to serialize Agent extensions'. This indicates a value inside the map that Jackson cannot serialize at all (e.g. a non-JSON Java object) — distinct from the per-value type guard which catches most cases first.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:163
}
if (extensions.size() > MAX_EXTENSIONS) {
throw new IllegalArgumentException(
"extensions exceeds " + MAX_EXTENSIONS + " entries");
}
for (Map.Entry<?, ?> entry : extensions.entrySet()) {
if (!(entry.getKey() instanceof String)) {
throw new IllegalArgumentException(
"Agent extensions contains a non-string JSON object key");
}
String key = (String) entry.getKey();
validateRequiredCodePointLength(key, MAX_EXTENSION_KEY_LENGTH, "extension key");
validateJsonValue(entry.getValue(), "extension " + entry.getKey());
}
final byte[] bytes;
try {
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;View on GitHub (pinned to 9b989acdf1)
Solutions
- Store only JSON-primitive compatible values (String, Boolean, Number, List, Map) in extensions; convert complex objects to Map/List first.
- Register/enable the needed Jackson modules only if you intentionally serialize richer types — but prefer plain structures.
- Reproduce locally with JacksonUtils.toJsonBytes(ext) to find the failing value.
Example fix
// before
ext.put("createdAt", Instant.now()); // Jackson fails without JavaTimeModule wiring
// after
ext.put("createdAt", Instant.now().toString()); // ISO-8601 string Defensive patterns
Strategy: validation
Validate before calling
try {
com.alibaba.nacos.common.utils.JacksonUtils.toJsonBytes(extensions);
} catch (NacosSerializationException e) {
throw new AgentExtUnserializableException(e);
} Try / catch
try {
AgentResourceExtSerializer.serialize(resourceExt);
} catch (IllegalArgumentException e) {
if ("Unable to serialize Agent extensions".equals(e.getMessage())) {
// a value in extensions is not JSON-serializable; replace complex objects with Map/String
sanitizeExtensions(extensions);
} else throw e;
} Prevention
- Store only JSON-primitive-compatible values (String, Boolean, Number, List, Map) in extensions.
- Convert Date/Instant/UUID/enum to strings before insertion.
- Avoid circular references and unregistered POJOs.
When it happens
Trigger: An extensions value is a Java object Jackson has no serializer for (a raw POJO without recognized shape, a self-referential structure, or a type with no default serialization), so the byte-size measurement step fails.
Common situations: Putting a domain object, a Date, a Joda/Java-time type, or a circular reference into extensions instead of a plain JSON-compatible value.
Related errors
- extensions exceeds 32 entries
- Agent extensions contains a non-string JSON object key
- Agent extensions exceeds {} bytes
- {} must be a finite JSON number
- {} contains a non-string JSON object key
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/b55c3fee3f2c0ac2.
Report an issue: GitHub.