An HTTP Request node can reach a server successfully and still receive something that cannot be parsed as JSON. Before changing expressions downstream, separate three observations: the status, the declared media type, and the actual body.
I made a small, reproducible Python fixture to make those differences visible. Both scripts and their measured output are in this diagnostic walkthrough. They use the standard library and temporary localhost fixtures; no API key or external service is needed.
What the six cases show
| Controlled case | Observation | What it establishes |
|---|---|---|
| 200 + valid JSON | JSON object decoded | Parsing succeeded; required application fields still need validation. |
| 200 + HTML | Non-JSON media type | Inspect the endpoint and authentication flow; HTML alone does not prove a particular cause. |
| 503 + JSON error body | HTTP failure | A readable JSON error is still a failed HTTP response. |
| 200 + JSON media type + broken body | Parsing fails | A Content-Type header is a claim, not validation of the bytes. |
| Connection refused | No HTTP status exists | The connection failed before an HTTP response. |
| 200 headers, body deliberately withheld | Body read times out | Receiving headers does not prove the body finished arriving. |
Applying the distinction to an n8n investigation
For an isolated diagnostic request, the HTTP Request node documentation describes Include Response Headers and Status and a Text response format. These let you inspect the response before assuming it is JSON. Changing the output format also changes what downstream nodes receive, so use a test copy with downstream actions disconnected.
Record the status if there is one, Content-Type, the failure phase, and a short redacted body excerpt where appropriate. If the body is HTML, inspect the expected endpoint and redirects. If it is a 503 response, investigate availability and the APIβs retry guidance. If declared JSON is malformed, retain a safe example for the producer. Avoid swallowing every failure into an empty object: that loses the evidence needed to distinguish the cases.
The documentation also describes Never Error, which changes handling of HTTP status codes. It does not turn a failed business operation into a successful one. Do not use it as proof that a request worked.
Reproduce and interpret carefully
Save the two scripts from the walkthrough as http_json_demo.py and http_transport_demo.py, then run each with Python 3. The first asserts four response cases; the second asserts a refused connection and a delayed body. The transport fixture was run on macOS with Python 3.12.3. Its short timeout is a deliberate test setting, not a production recommendation.
These are executed Python fixtures. The n8n settings above are documentation-based guidance; I have not validated this fixture inside an n8n workflow. In particular, the Python body-read timeout is not a claim about n8nβs timeout semantics. The scripts start and stop their own test servers; they are not persistent URLs to paste into n8n Cloud or Docker.
Keep credentials and real customer payloads out of public screenshots or replies. A sanitized failure phase, status and media type are usually a more useful starting point than only βJSON parsing failed.β
