Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This Jackson error means your Java target type expects a list, but the JSON payload starts as an object. In short, the structure of your class does not match the structure of incoming JSON. The fix is to map the root shape correctly and deserialize into the right type.
What the Error Message Actually Tells You
The phrase out of START_OBJECT token indicates the parser saw object-start at root while your code asked for ArrayList or List<T> root.
Typical mismatch:
- expected: JSON array root
- received: JSON object root containing an array field
Array root example:
Object root example:
These require different Java target types.
Correct Mapping for Array Root
When payload root is an array, deserialize with TypeReference<List<Item>>.
This succeeds because root type and Java target type align.
Correct Mapping for Object Wrapper Root
When payload root is object wrapper, create DTO for wrapper and deserialize into it.
Do not deserialize wrapped payload directly to list.
Typical API Integration Pattern
Many APIs return metadata and data together. Examples include page index, total count, cursor, and items list. In those APIs, list-only mapping is incorrect even if items field exists.
A robust response model usually includes:
- metadata fields
- list payload field
- optional error fields
Modeling full contract improves resilience when API evolves.
If endpoint versions differ, keep separate DTOs per version rather than one mutable class with optional fields for every era.
Debugging Workflow When Error Appears
A practical diagnosis sequence:
- capture raw JSON at integration boundary.
- inspect root token type quickly.
- compare with current target class.
- adjust DTO shape or endpoint parser route.
For quick root-token check, you can parse tree first:
This helps when contracts are unclear or provider docs are outdated.
Hardening Against Contract Drift
To avoid runtime surprises in production:
- keep fixture JSON samples in tests
- validate root shape in integration tests
- pin client parsing logic to endpoint version
- fail fast with explicit parser errors
Avoid broad catch blocks that silently fallback to generic maps. They hide schema problems and create delayed failures downstream.
If payload field names differ from Java naming conventions, use @JsonProperty explicitly instead of relying on implicit naming assumptions.
Common Pitfalls
Deserializing object-root payload directly into list type causes immediate token mismatch errors.
Assuming all endpoints return same root shape leads to fragile shared parsing helpers.
Using untyped List<Object> or raw maps for core domain paths makes validation weak and maintenance harder.
Ignoring parser error details wastes debugging time because the message already indicates root mismatch.
Summary
- This error is usually a root JSON shape mismatch, not a Jackson bug.
- Match Java target type to actual payload root token.
- Use
TypeReference<List<T>>only for array-root payloads. - Use wrapper DTOs for object-root payloads with nested lists.
- Add contract-shape tests to catch API drift before runtime failures.

