JSON troubleshooting
Jackson: Cannot deserialize value of type from Array or Object value
Fix Jackson MismatchedInputException when JSON arrays, objects and strings do not match your Java types, including the older START_ARRAY and START_OBJECT messages.
What the error means
The JSON is valid, but its shape does not match the Java type Jackson was asked to build. from Object value means Jackson found a JSON object where the type expects something else, such as a list. from Array value means it found an array where it expected an object or a single value. The message names the target type and the JSON token. Versions before 2.12 said out of START_OBJECT token or out of START_ARRAY token for the same mismatch.
Exact messages by runtime
Messages depend on the input and runtime version. Node and Python rows were reproduced locally. Other rows cite official documentation or source. Rows marked as fragments or templates preserve the source wording and are not complete exception transcripts. Browsers and libraries may append location details.
| Runtime | Message | Input and evidence |
|---|---|---|
| Java / Jackson 2.12+ and 3.x, list target | MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<com.example.Item>` from Object value (token `JsonToken.START_OBJECT`) | readValue("{\"items\":[]}", new TypeReference<List<Item>>() {})Source-derived from the Jackson 2.22 template; the type text depends on your class |
| Java / Jackson 2.12+ and 3.x, object target | Cannot deserialize value of type `com.example.Item` from Array value (token `JsonToken.START_ARRAY`) | readValue("[{\"id\":1}]", Item.class)Source-derived from the same template |
| Java / Jackson 2.12+ and 3.x, String field | Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`) | {"address":{"city":"Pune"}} into a String address fieldSource-derived; the reference chain suffix is omitted |
| Java / Jackson 2.10 and 2.11 | Cannot deserialize instance of `java.util.ArrayList<com.example.Item>` out of START_OBJECT token | The list exampleSource-derived from the Jackson 2.11.4 template |
| Java / Jackson 2.9 | Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token | The list exampleSource-derived from the Jackson 2.9.10.8 template |
| Java / Jackson 2.8 and earlier | Can not deserialize instance of java.util.ArrayList out of START_OBJECT token | The list exampleSource-derived from the Jackson 2.8.11 template |
| C# / Json.NET | Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type '{0}' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. | An object where a List<T> is expectedJson.NET 13.0.4 source template; first sentence shown |
| Go / encoding/json | json: cannot unmarshal object into Go value of type []main.Item | The list example in GoSource-derived from Go 1.27 decode.go |
Causes you can reproduce
The response wraps the list in an object
Many APIs return {"items": [...]} or {"data": [...]}. Reading that object as a List fails with from Object value.
record Item(long id) {}
String json = "{\"items\":[{\"id\":1}]}";
List<Item> items = new ObjectMapper().readValue(json, new TypeReference<List<Item>>() {});
// MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<...Item>` from Object valueOne value arrives where a list is expected
Some APIs send a single object or string when there is one result and an array when there are several. A List field then sees an object or a string.
record Order(List<String> tags) {}
new ObjectMapper().readValue("{\"tags\":\"new\"}", Order.class);
// MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<java.lang.String>` from String valueA field type differs from the JSON value
A String field cannot hold a nested object, and a single object field cannot hold an array.
record User(String address) {}
new ObjectMapper().readValue("{\"address\":{\"city\":\"Pune\"}}", User.class);
// Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)How to fix it
- Read the target type and the JSON token. The (through reference chain: ...) suffix names the class and property where it failed.
- Look at the JSON at that property. An object starts with {, an array with [.
- Change the Java type to match: a wrapper record for {"items": [...]}, a List or array for [...], and a nested record for {...}.
- If the API really sends either one value or a list, enable ACCEPT_SINGLE_VALUE_AS_ARRAY and document that contract.
Model the wrapper object
Records need Jackson 2.12 or later. The fragments run in a method that declares throws Exception.
record Item(long id) {}
record ItemsResponse(List<Item> items) {}
ItemsResponse response = new ObjectMapper()
.readValue("{\"items\":[{\"id\":1}]}", ItemsResponse.class);
List<Item> items = response.items();Read a top-level array as a list
TypeReference keeps the element type, so each element becomes an Item instead of a Map.
List<Item> items = new ObjectMapper()
.readValue("[{\"id\":1}]", new TypeReference<List<Item>>() {});Accept one value as a one-element list
Enable this only when the API documents both forms.
ObjectMapper mapper = JsonMapper.builder()
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.build();
Order order = mapper.readValue("{\"tags\":\"new\"}", Order.class); // tags = [new]Compare the JSON shape with your types
- Copy the exact JSON your code received, for example from a log or a failing test.
- Paste it into the Tool Kumar JSON viewer. The document stays in your browser.
- Open the tree at the property named in the error and check whether the value there is an object, an array or a single value. The JSON path finder copies the path to any value.
- Generate types from the same document with a converter listed under related tools, then compare them with your own classes or structs.
Frequently asked questions
What do START_OBJECT and START_ARRAY mean?
They are Jackson token names for { and [. Newer messages say Object value and Array value instead, and add the token name in parentheses.
Why does the message say ArrayList when my code asks for List?
Jackson builds an ArrayList for an abstract List type, so the message names the concrete type it tried to create.
Is this a JSON syntax error?
No. The document parsed successfully. The error is a mismatch between the JSON structure and your Java types, so fix the types or the producer, not the syntax.
Should I enable ACCEPT_SINGLE_VALUE_AS_ARRAY globally?
Only if every list in your input may arrive as a single value. Otherwise it hides real contract changes. You can enable it per property with @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY).
Related errors and tools
- Jackson: Unrecognized field, not marked as ignorable
- Jackson: Unrecognized token / Unexpected character ('<' (code 60))
- Go JSON: cannot unmarshal string, object or array into Go value
- All JSON error guides
- JSON syntax reference
- Generate Java records from the JSON you received
- Find the path to the value that failed
Standards and diagnostic sources
RFC 8259 and ECMA-404 define JSON syntax. Diagnostic wording belongs to the parser. The table links each cited message to its source.