204 No Content
Success
The request succeeded but the server is intentionally not returning a response body. The response can include headers such as Cache-Control or ETag, but per the spec the body must be empty and clients should not expect any payload. 204 is the right answer when a client does not need the result of an action. DELETE, idempotent PUT, PATCH, and CORS preflight all commonly use it.
When does this happen?
Return 204 when the request succeeded and there is no useful body to send. The canonical case is DELETE. The resource is gone, there is nothing left to describe. PUT and PATCH endpoints sometimes use 204 instead of 200 when the client already has the updated state. A 204 is also the standard response for a successful OPTIONS preflight in CORS, where the browser only cares about the Access-Control-* headers. Browsers handle 204 differently from 200: a 204 returned from a fetch will leave the current page in place if the request was initiated by a form submit, and JavaScript code calling fetch must check status before calling response.json() because parsing an empty body will throw. 204 must never carry a message body. A body in a 204 response is a protocol violation and some intermediaries will strip it silently while others will choke on it.
Common causes
- Successful DELETE on a resource. The server removed it and has nothing to describe.
- Successful CORS preflight (OPTIONS) returning Access-Control-Allow-* headers and no body.
- PUT or PATCH where the server intentionally omits the updated resource because the client already has it.
- Heartbeat or telemetry ingestion endpoint that accepts the payload and acknowledges with no response data.
- Toggle endpoint like POST /v1/sessions/{id}/end where the action has no return value beyond success.
- Bulk operation that completed synchronously and the caller did not request a summary.
How to fix it
- No fix needed when this is intentional. Verify clients tolerate an empty body by checking status before parsing.
- If your fetch wrapper calls response.json() unconditionally, guard it: if (response.status !== 204) return response.json().
- Strip any accidental body from 204 responses. Some frameworks include whitespace or a newline that violates the spec.
- If you find yourself needing to return data with a 204, switch to 200. The spec forbids 204 with a body.
- For CORS preflight, confirm the response includes Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers. Without them the actual request will fail even though the preflight returned 204.
- Document 204 explicitly in your API spec so client generators know to expect no body.
Real-world examples
- Client sends DELETE /v1/posts/123 to remove a blog post they own.
- Server deletes the row, returns 204 with no body. Client treats it as success and removes the post from its local UI.
- Browser issues an OPTIONS preflight for a cross-origin POST to api.example.com.
- Server returns 204 with Access-Control-Allow-Origin and friends. Browser proceeds with the actual POST.
- Analytics SDK fires beacon POSTs to /collect with event payloads.
- Server returns 204 with no body. The SDK considers the event delivered and moves on without parsing anything.
- User clicks a Like button that calls PUT /v1/posts/123/like.
- Server records the like and returns 204. UI optimistically updates the like count without waiting for a body.
Debugging
- Run curl -i -X DELETE https://example.com/v1/posts/123 and confirm the response is HTTP/1.1 204 No Content with no body.
- Verify Content-Length is 0 or absent and that there is no Transfer-Encoding: chunked. Both indicate a body where there should not be one.
- For preflight failures, check the actual OPTIONS request in DevTools Network tab and confirm the Access-Control-Allow-* headers match what your real request needs.
- If a client crashes on 204, search its source for response.json() or response.text() calls that do not guard on status.
How it differs from related codes
HTTP 200
200 carries a body describing the result. 204 is identical in success semantics but explicitly carries no body. Use 204 when there is nothing useful to say.
HTTP 205
205 (Reset Content) tells the client to reset its form or view. 204 makes no such instruction. The client should leave its UI state untouched.
HTTP 201
201 implies creation happened and usually includes a body or a Location header. 204 is silent about creation and carries nothing.
Related status codes
See HTTP 204 in your redirect chains?