Question

How to Fix Jackson "No Creators, like default construct, exist" Error in Java Retrofit Deserialization

kotlinandroidserializationjacksonretrofit2

Question

I am consuming an API in a Java application using Retrofit and Jackson for JSON deserialization. During the request, Retrofit triggers onFailure with this Jackson error:

No Creators, like default construct, exist: cannot deserialize from Object value (no delegate- or property-based Creator)

Why does this happen, and how can I fix my model class so Jackson can deserialize the API response correctly?

Short Answer

By the end of this page, you will understand what Jackson means by a Creator, why Retrofit surfaces this error during deserialization, and how to fix your Java model classes using a no-argument constructor, @JsonCreator, and @JsonProperty when needed.

Concept

Jackson converts JSON into Java objects by creating an instance of your class and then filling in its fields or calling its constructor parameters.

That error means Jackson received a JSON object like this:

{
  "id": 1,
  "name": "Alice"
}

but it could not figure out how to create the Java object first.

In Jackson, a Creator is a way to build an object during deserialization. Common options are:

  • a public no-argument constructor
  • a constructor annotated with @JsonCreator
  • constructor parameters annotated with @JsonProperty
  • a builder pattern configured for Jackson

If your class only has a constructor with parameters and no default constructor, Jackson often cannot instantiate it automatically unless you explicitly tell it how.

This matters in real programming because API clients depend on reliable mapping between JSON responses and Java classes. If your models are not deserialization-friendly, network calls may succeed but object mapping will fail.

Mental Model

Think of Jackson as a delivery worker bringing JSON data to your Java class.

  • The JSON is the package.
  • Your Java class is the apartment.
  • Jackson must first get inside the apartment before placing the items.

If the apartment has an unlocked front door, that is like a no-argument constructor.

If the apartment requires a special entry code, that is like a constructor with parameters. Jackson needs clear instructions about which values go where. Those instructions are provided with @JsonCreator and @JsonProperty.

Without a door or instructions, Jackson stands outside and throws the "No Creators" error.

Take Quiz

Syntax and Examples

Basic fix: add a no-argument constructor

If your class uses mutable fields or setters, the simplest fix is often to add a default constructor.

public class User {
    private int id;
    private String name;

    public User() {
        // Default constructor required by Jackson
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Jackson can now:

  1. call new User()
  2. set id
  3. set name

Alternative fix: use @JsonCreator

If you want immutable objects, use a constructor and tell Jackson how to map JSON fields.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private final int id;
    private final String name;

    @JsonCreator
    public User(
        @JsonProperty("id") int id,
        @JsonProperty("name") String name
    ) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

This tells Jackson exactly how to build the object from JSON.

Typical Retrofit API interface

public interface ApiService {
    @GET("users/1")
    Call<User> getUser();
}

If the response JSON matches the User class, Retrofit and Jackson can deserialize it successfully.

Step by Step Execution

Consider this JSON response:

{
  "id": 10,
  "name": "Maya"
}

And this Java class:

public class User {
    private int id;
    private String name;

    public User() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

What Jackson does:

  1. Reads the JSON object.
  2. Sees that it needs a User object.
  3. Looks for a way to create User.
  4. Finds public User().
  5. Creates a new User instance.
  6. Finds id in JSON and calls setId(10).
  7. Finds name in JSON and calls setName("Maya").
  8. Returns the completed object.

Now consider this broken class:

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

What happens here:

  1. Jackson reads the JSON object.
  2. It needs a User instance.
  3. It does not find a no-argument constructor.
  4. It sees a parameterized constructor, but it does not know which JSON fields map to which parameters.
  5. It throws the "No Creators" error.

Fixing it with annotations:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private final int id;
    private final String name;

    @JsonCreator
    public User(
        @JsonProperty("id") int id,
        @JsonProperty("name") String name
    ) {
        this.id = id;
        this.name = name;
    }
}

Real World Use Cases

This issue appears often in API-driven Java applications.

Mobile or Android apps using Retrofit

A request succeeds, but parsing fails because the response model has only custom constructors.

Backend services consuming other APIs

A service calls an external API and maps the result into DTOs. If the DTOs are immutable but not annotated correctly, deserialization breaks.

JSON config loading

Applications often load JSON configuration into Java objects. Jackson still needs a valid way to create each object.

Data transfer objects in layered apps

Controllers, services, and clients often use DTO classes. These classes must be designed with serialization and deserialization in mind.

Take Quiz

Real Codebase Usage

In real projects, developers usually choose one of these patterns:

1. Mutable DTOs with no-arg constructors

Common in simple apps and generated models.

public class ProductDto {
    private String sku;
    private double price;

    public ProductDto() {}

    public String getSku() { return sku; }
    public void setSku(String sku) { this.sku = sku; }

    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

2. Immutable DTOs with @JsonCreator

Common when developers want safer objects.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ProductDto {
    private final String sku;
    private final double price;

    @JsonCreator
    public ProductDto(
        @JsonProperty("sku") String sku,
        @JsonProperty("price") double price
    ) {
        this.sku = sku;
        this.price = price;
    }

    public String getSku() { return sku; }
    public double getPrice() { return price; }
}

3. Validation after deserialization

Developers often deserialize first, then validate required fields.

if (user.getName() == null || user.getName().isBlank()) {
    throw new IllegalArgumentException("Name is required");
}

4. Mapping API models to domain models

Large codebases often keep Retrofit/Jackson models separate from business objects.

User apiUser = response.body();
DomainUser domainUser = new DomainUser(apiUser.getId(), apiUser.getName());

This keeps serialization concerns out of core business logic.

Common Mistakes

1. Only defining a parameterized constructor

This is the most common cause.

Broken

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Fix

  • add a no-argument constructor, or
  • annotate the constructor with @JsonCreator and @JsonProperty

2. Missing getters and setters for mutable classes

If Jackson relies on setters and they do not exist, field population may fail.

public class User {
    private int id;
}

Safer version:

public class User {
    private int id;

    public User() {}

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

3. JSON field names do not match Java property names

If the API returns full_name but your class uses fullName, mapping may fail unless configured.

import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    @JsonProperty("full_name")
    private String fullName;

    public User() {}

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}

4. Using final fields without a creator constructor

final fields usually mean values must be set in the constructor. If Jackson cannot use that constructor, deserialization fails.

5. Assuming onFailure always means network failure

With Retrofit, converter errors may also appear in failure paths depending on setup. Always inspect the exception message and stack trace.

6. Nested classes not deserializable

If your response contains nested objects, every nested class must also be deserializable.

Comparisons

ApproachHow Jackson creates objectBest forProsCons
No-arg constructor + settersCreate empty object, then set fieldsSimple DTOsEasy to understandMutable objects
@JsonCreator + @JsonPropertyCall constructor with JSON valuesImmutable DTOsClear mapping, safer objectsMore verbose
Public fieldsDirect field accessQuick prototypesMinimal codeLess encapsulation
Builder patternUse configured builderComplex objectsFlexible for large modelsMore setup

No-arg constructor vs @JsonCreator

  • Use a no-arg constructor when you are okay with mutable objects.
  • Use @JsonCreator when you want constructor-based deserialization and immutable fields.

Retrofit vs Jackson responsibility

ToolResponsibility
RetrofitMakes HTTP requests and routes responses
JacksonConverts JSON into Java objects

Retrofit is usually not the root cause here. The problem is normally in the Jackson model mapping.

Take Quiz

Cheat Sheet

// Option 1: mutable class
public class User {
    private int id;
    private String name;

    public User() {}

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}
// Option 2: immutable class
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private final int id;
    private final String name;

    @JsonCreator
    public User(@JsonProperty("id") int id,
                @JsonProperty("name") String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() { return id; }
    public String getName() { return name; }
}

Remember

  • Jackson must know how to instantiate your class.
  • A no-arg constructor is the simplest solution.
  • If using constructor parameters, annotate them.
  • JSON names must match Java property names, or use @JsonProperty.
  • Nested response classes must also be deserializable.
  • Inspect stack traces: parsing errors are not the same as connection errors.

FAQ

Why does Jackson say "No Creators"?

Jackson cannot find a valid way to create an instance of your class during deserialization.

Do I always need a default constructor?

No. You can also use a constructor annotated with @JsonCreator and parameter names annotated with @JsonProperty.

Why does this happen in Retrofit onFailure?

Retrofit uses Jackson to parse the response. If parsing fails, the call may end up in the failure path depending on your adapter and converter setup.

Can private fields still be deserialized?

Yes, often they can, especially with getters/setters or Jackson configuration. But the object still needs a valid creation method.

What if my JSON field names are different from my Java fields?

Use @JsonProperty("json_name") to map them correctly.

Does this error mean the API response is invalid?

Not always. The JSON may be perfectly valid, but your Java class may not be compatible with Jackson deserialization.

Should I use mutable or immutable DTOs?

Both are valid. Mutable DTOs are simpler for beginners. Immutable DTOs are safer and often preferred in larger codebases.

Take Quiz

Mini Project

Description

Create a small Java model for an API response representing a book. The purpose is to practice building a Jackson-friendly class that Retrofit can deserialize without throwing the "No Creators" error.

Goal

Build a response model that correctly deserializes JSON for a book object using constructor-based mapping.

Requirements

  • Create a Book class with id, title, and author fields.
  • Make the fields immutable using final.
  • Use Jackson annotations so the class can be deserialized from JSON.
  • Add getter methods for each field.
  • Test it against a JSON object with matching keys.
Take Quiz

Keep learning

Related questions

View more