Loading

HTTP Requester target on HTTP 204 No Content causes "Unable to parse empty input, while reading `<variable>` as Json

Publiseringsdato: May 4, 2026
Beskrivelse

The user encountered an issue where the HTTP Request feature of the HTTP module creates a target variable with no content when receiving a 204 No Content response. This disrupts downstream processes, as attempts to parse the variable as JSON result in an error.

Symptoms
- An outbound HTTP Requester receives `HTTP/1.1 204 No Content` from a third-party API.
- The requester itself raises no error (204 is a 2xx success code).
- The configured `target` variable is created, so null-checks such as `vars.myVar != null` return `true`.
- Any subsequent DataWeave expression that reads the variable — including `isEmpty(vars.myVar)` — throws:

Error Message

org.mule.weave.v2.module.reader.ReaderParsingException:
Unable to parse empty input, while reading `<variable>` as Json.

Environment
- Mule Runtime: 4.4.x / 4.5.x / 4.6.x / 4.9.x (all observed)
- Connector: HTTP Connector 1.7.x – 1.10.x
- Deployment: CloudHub 1.0 / CloudHub 2.0 / RTF / On-Prem — behaviour identical across targets

 

Cause

Two things combine:

1. The remote server returns a malformed 204.** Per RFC 7230 §3.3.2 and RFC 7231 §6.3.5, a `204 No Content` response MUST NOT include a message body and should not advertise a `Content-Type`. Several third-party APIs (including some AWS API Gateway–fronted services) return 204 with headers such as:

   HTTP/1.1 204 No Content
   Content-Type: application/json
   Content-Length: 0
  
   The "Content-Type: application/json" on a zero-byte body is the root defect — there is no JSON document.

2. The Mule HTTP Requester faithfully reflects the wire response. The `target` variable is populated with an empty `CursorStreamProvider` (or empty byte array, depending on streaming strategy) whose DataWeave MIME type is inherited from the server's `Content-Type` header. The stream exists, so it is not `null`. When any downstream expression touches the variable — a Transform, a `logger`, a `choice` predicate, even `isEmpty()` — DataWeave coerces the empty payload from `application/json`, and a zero-byte input is not a legal JSON document (not even `null`, which is 4 bytes). The parser raises `Unable to parse empty input`.

This is working-as-designed on the Mule side: auto-converting any empty 2xx body to `null` would be a breaking change for flows that rely on a typed empty payload (HEAD requests, 200s with `Content-Length: 0` used as success sentinels, binary passthrough, proxy-style flows). 

Løsning
Option 1 — Fix the upstream API (best long-term)
Ask the third-party API owner to either:
- Drop `Content-Type` from the 204 response, **or**
- Return `HTTP 200` with an empty JSON body `{}` / `[]` if they want to signal "call succeeded, no rows".

 

A spec-compliant 204 (no body, no content-type) does **not** trigger this error in Mule.

 

Option 2 — Branch on the status code before reading the body (recommended)
 
<http:request config-ref="Target_API_Config"
method="POST"
path="/resource"
target="resp"
targetValue="#[payload]">
<http:response-validator>
<http:success-status-code-validator values="200..299"/>
</http:response-validator>
</http:request>

<choice doc:name="Handle 204">
<when expression="#[attributes.statusCode == 204]">
<set-variable variableName="result" value="#[null]"/>
</when>
<otherwise>
<set-variable variableName="result" value="#[vars.resp]"/>
</otherwise>
</choice>


Clearest intent, works regardless of what `Content-Type` the server sent on the 204.

Option 3 — Size-check the raw bytes, then parse explicitly
For existing DataWeave that cannot easily be wrapped in a `choice`:
```dataweave
%dw 2.0
output application/json
---
if (sizeOf(vars.resp default "" as Binary) == 0)
null
else
read(vars.resp, "application/json")
 
`read(..., "application/json")` forces an explicit parse rather than relying on the inbound `Content-Type`, but only after a size check confirms there are bytes to parse. `sizeOf` on a `Binary` does not trigger the JSON reader.

Option 4 — Override the requester's outputMimeType
If the flow never wants the requester to auto-parse, set `outputMimeType="application/octet-stream"` on the operation. The target variable becomes a raw binary; DataWeave will not try to coerce it until the flow explicitly calls `read(..., "application/json")`. Use sparingly — it changes behaviour for **all** responses from that requester, not just 204s.


 

Knowledge-artikkelnummer

005321690

 
Laster
Salesforce Help | Article