๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGjava.lang.IllegalStateException: ResponseEntity has already been built at org.springframework.http.ResponseEntity$BodyBuilder.headers(ResponseEntity.java:282) at com.devinhyderabad.controller.MyController.getUser(MyController.java:45)

โšก Quick Fix Works 80% of the time

Chain all builder methods (.headers, .body) together in a single return statement.

return ResponseEntity.ok() .headers(headers) .body(user);

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

The ResponseEntity builder pattern creates an immutable object once .body() or .build() is called. If your code tries to call .headers() or .contentType() on a ResponseEntity that has already been finalized, Spring throws this exception.

The HITEC City Parking Spot Analogy:

Imagine baking a cake. Once you put it in the oven and it is baked (.body()), you cannot go back and add more sugar to the batter. You must start a new cake if you want to change the recipe.

๐Ÿ” How to Reproduce Confirm this is your error

Call .headers() on a ResponseEntity.BodyBuilder, store the builder in a variable, then try to call .body() separately. You get IllegalStateException: ResponseEntity has already been built.

๐Ÿ› ๏ธ Solutions (3 Ways to Fix)

Solution 1โœ“ Most common cause

Chain builder methods

๐Ÿ‘‰ Use this if you are splitting ResponseEntity creation across multiple lines.

Once you call .build() or .body(), the ResponseEntity is finalized. You cannot modify it afterwards. Chain the methods.

// BAD ResponseEntity.BodyBuilder builder = ResponseEntity.ok(); builder.headers(headers); return builder.body(user); // Might throw error if modified later // GOOD return ResponseEntity.ok() .headers(headers) .body(user);
Solution 2

Do not modify ResponseEntity in @ControllerAdvice after returning

๐Ÿ‘‰ Use this if you have an interceptor or advice trying to add headers.

Once the controller returns the ResponseEntity, Spring starts writing the HTTP response. Interceptors cannot modify the body or add headers easily.

// In an Interceptor: postHandle // response.setHeader("X-Custom", "value"); // Use HttpServletResponse, not ResponseEntity
Solution 3

Return a fresh ResponseEntity

๐Ÿ‘‰ Use this if you need to completely change the response.

Instead of trying to modify an existing one, create a new ResponseEntity object.

if (condition) { return ResponseEntity.notFound().build(); } else { return ResponseEntity.ok(user); }

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Standard ResponseEntity builder.

Spring Boot 3.x

Identical builder API.

๐Ÿ›ก๏ธ How to Prevent This Next Time

Always construct ResponseEntity in a single, fluent return statement. Do not store partial builders in variables.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase