Jackson's 'No Creators' Error: How to Fix InvalidDefinitionException

beginnerโ˜• Java2026-07-28| Java (JDK 8+), Jackson Databind 2.x, Spring Boot, Lombok

Error Message

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.dto.UserDTO` (no Creators, like default constructor, exist)
#java#jackson#json#deserialization#lombok

Decoding the Error

Jackson is the industry standard for JSON processing in Java, but it is notoriously picky about how it builds objects. If you see the following stack trace, Jackson is telling you it doesn't know how to instantiate your class:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.dto.UserDTO` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"name":"John"}"; line: 1, column: 2]

The Root Cause

Jackson usually needs a no-argument constructor to create an empty object before filling it with data via reflection or setters. This error typically surfaces in four specific scenarios:

  • The Missing Default: You added a custom constructor with arguments. In Java, once you define any constructor, the compiler stops providing the default no-args constructor automatically.
  • Lombok Conflicts: You are using @Builder or @AllArgsConstructor, which hides the default constructor Jackson requires.
  • Inner Class Scope: Your DTO is an inner class but lacks the static keyword. Jackson cannot instantiate a non-static inner class without a reference to the outer class.
  • Immutability: You marked your fields as final, but didn't tell Jackson how to map JSON keys to your constructor parameters.

Practical Solutions

1. Restore the No-Argument Constructor

Adding a manual constructor is the fastest fix. Even if it is empty, Jackson can use it to bootstrap the object creation process.

public class UserDTO {
    private Long id;
    private String name;

    // Required for Jackson deserialization
    public UserDTO() {}

    public UserDTO(Long id, String name) {
        this.id = id;
        this.name = name;
    }
}

2. Configure Lombok for Jackson

Lombok is a great tool, but it often causes this specific error. If you use @Data or @Builder, you must explicitly add @NoArgsConstructor. For classes with final fields, use the force attribute to initialize those fields to default values (null, 0, false) during instantiation.

import lombok.*;

@Data
@NoArgsConstructor(force = true) // Creates the default constructor Jackson needs
@AllArgsConstructor
@Builder
public class UserDTO {
    private final Long id;
    private final String name;
}

3. Handle Immutable Objects with @JsonCreator

If you prefer strictly immutable DTOs, you don't need a no-args constructor. Instead, point Jackson to your existing constructor using @JsonCreator. You must also label each argument with @JsonProperty so Jackson knows which JSON key maps to which parameter.

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

public class UserDTO {
    private final Long id;
    private final String name;

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

4. Enable Java 8 Parameter Names

Writing @JsonProperty for every field is tedious. If you are using Java 8 or higher, you can compile your code with the -parameters flag. This allows Jackson to see the actual names of your constructor arguments at runtime. To make this work, register the ParameterNamesModule in your ObjectMapper configuration.

ObjectMapper mapper = new ObjectMapper()
    .registerModule(new ParameterNamesModule())
    .registerModule(new Jdk8Module());

// Now Jackson can find the constructor without extra annotations
UserDTO user = mapper.readValue(jsonString, UserDTO.class);

5. Static Inner Classes

Always check your nested classes. If UserDTO lives inside another class, it must be static. Without this, Jackson would need an instance of the parent class to exist first, which is impossible during standard JSON parsing.

Verifying the Fix

Don't guess; test. Use a simple JUnit test case to ensure your DTO is compatible with Jackson. This prevents regression errors when team members update Lombok annotations later.

@Test
void verifyDeserialization() throws Exception {
    String json = "{\"id\":101, \"name\":\"Jane Doe\"}";
    UserDTO result = new ObjectMapper().readValue(json, UserDTO.class);
    
    assertNotNull(result);
    assertEquals(101L, result.getId());
}

Prevention Checklist

  • Standardize: Make @NoArgsConstructor a default addition to all DTOs in your project.
  • Validation: Use a JSON Formatter to ensure your input isn't malformed. A missing bracket can sometimes lead Jackson to misidentify the object structure.
  • Kotlin: If your project uses Kotlin, always include the jackson-module-kotlin. It handles the absence of default constructors in data classes automatically.

Related Error Notes