eclipse-vertx/vert.x · error · DecodeException
Failed to decode
Error message
Failed to decode
What it means
JacksonCodec.cast narrows a decoded value to the requested class. When the decoded value is a Map but the target class cannot accept a Map (clazz.isAssignableFrom(Map.class) is false), it throws DecodeException("Failed to decode"). This means the JSON document was an object but you asked to decode it into an incompatible type (e.g. a List or String class).
Source
Thrown at vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/JacksonCodec.java:465
} else if (json instanceof Float) {
generator.writeNumber((Float) json);
} else if (json instanceof Double) {
generator.writeNumber((Double) json);
} else if (json instanceof Byte) {
generator.writeNumber((Byte) json);
} else if (json instanceof BigInteger) {
generator.writeNumber((BigInteger) json);
} else if (json instanceof BigDecimal) {
generator.writeNumber((BigDecimal) json);
} else {
generator.writeNumber(((Number) json).doubleValue());
}
}
private static <T> T cast(Object o, Class<T> clazz) {
if (o instanceof Map) {
if (!clazz.isAssignableFrom(Map.class)) {
throw new DecodeException("Failed to decode");
}
if (clazz == Object.class) {
o = new JsonObject((Map) o);
}
return clazz.cast(o);
} else if (o instanceof List) {
if (!clazz.isAssignableFrom(List.class)) {
throw new DecodeException("Failed to decode");
}
if (clazz == Object.class) {
o = new JsonArray((List) o);
}
return clazz.cast(o);
} else if (o instanceof String) {
String str = (String) o;
if (clazz.isEnum()) {
o = Enum.valueOf((Class<Enum>) clazz, str);
} else if (clazz == byte[].class) {View on GitHub (pinned to fb308bd8c3)
Solutions
- Match the target type to the JSON shape: use Map.class/JsonObject.class for objects, List.class/JsonArray.class for arrays
- Decode without a target class (Json.decodeValue(buffer)) and convert manually, or use a POJO mapping with jackson-databind available
- If the payload changed shape, update the producer or adapt the consumer's expected type
Example fix
// before
Map<String,Object> m = Json.decodeValue("{\"a\":1}", List.class); // DecodeException: Failed to decode
// after
Map<String,Object> m = Json.decodeValue("{\"a\":1}", Map.class);
// or: JsonObject o = Json.decodeValue("{\"a\":1}", JsonObject.class); Defensive patterns
Strategy: type-guard
Validate before calling
String t = input.trim();
if (!t.startsWith("{")) throw new IllegalArgumentException("payload is not a JSON object"); Type guard
static <T> boolean decodableAsMap(Class<T> c) {
return c == Object.class || c.isAssignableFrom(Map.class);
} Try / catch
try {
T v = Json.decodeValue(buffer, targetType);
} catch (DecodeException e) {
if ("Failed to decode".equals(e.getMessage())) {
// JSON shape does not match target type; decode without target and inspect
Object raw = Json.decodeValue(buffer);
}
} Prevention
- Match decode target to payload shape: Map/JsonObject for objects
- Avoid decoding object payloads into POJO classes when jackson-databind is absent
- Pin API response shapes with contract tests to catch producer drift
When it happens
Trigger: Calling JacksonCodec.cast(mapValue, SomeClass) or decoding JSON with Json.decodeValue(buffer, X.class) where the JSON is an object and X is not Map, Object, JsonObject, or any supertype of Map — e.g. decodeValue(json, List.class) on '{"a":1}'.
Common situations: Decoding an API response that changed from an array to an object while the target type stayed List; asking for a POJO class without databind on the classpath so the raw Map cannot be mapped onto it; passing Integer.class/String.class for object-shaped JSON.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Expecting the current parser token to be the start of an obj
- Expecting the current parser token to be the start of an arr
- Unexpected trailing token
- Expecting the current parser token to be the start of an obj
- Expecting the current parser token to be the start of an arr
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/235856e8f8a3d6e3.
Report an issue: GitHub.