Hello n8n community,
I’m facing a strange issue with the HTTP Request node that I can’t solve. I’m trying to send a POST request to an API, but it fails with a 400 error saying the “Content-Type” header is missing, even though it is configured.
The strangest part is that an identical cURL command, run from the same self-hosted server, works perfectly.
Here are the details: n8n Version: 1.112.5 (Self-hosted)
1. The Successful cURL Command:
(This command runs on my server and successfully creates the customer) curl --request POST --url 'https://app.pennylane.com/api/external/v2/company_customers' --header 'Authorization: Bearer <MY_API_KEY>' --header 'Content-Type: application/json' --header 'Accept: application/json' --data '{"name": "Client Test Monoline","billing_address": {"address": "1 Rue de la Console","postal_code": "75001","city": "Paris","country_alpha2": "FR"}}'
2. The Failing n8n HTTP Request Node:
Here is the JSON of my node configuration: PASTEZ_ICI_LE_JSON_DE_VOTRE_NOEUD (Pour obtenir ce JSON, cliquez sur votre nœud HTTP Request, faites Ctrl+C, puis collez-le ici)
3. The Error in n8n: 400 - "Content-Type" request header must be set to "application/json".
As you can see, the n8n node is configured to be identical to the working cURL command (manual Authorization header, Content-Type, Accept, Raw body), but it fails.
Does anyone have an idea why the n8n node would behave differently from cURL in this situation? Is this a known bug?
Thank you for your help!
Hello, and thank you for the quick reply.
You are right, I forgot to include the node's JSON. Here is the complete JSON for the failing HTTP Request node:
```json
{
"nodes": [
{
"parameters": {
"method": "POST",
"url": "[https://app.pennylane.com/api/external/v2/company_customers](https://app.pennylane.com/api/external/v2/company_customers)",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
},
{
"name": "User-Agent",
"value": "curl/7.81.0"
}
]
},
"sendBody": true,
"contentType": "raw",
"body": "{\"name\": \"Client Test N8N Final\",\"billing_address\": {\"address\": \"1 Rue de la Victoire\",\"postal_code\": \"75001\",\"city\": \"Paris\",\"country_alpha2\": \"FR\"}}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"credentials": {
"httpHeaderAuth": {
"id": "Hr8MZQ5AiLZxRmYD",
"name": "Pennylane LScompta"
}
}
}
],
"connections": {}
}
Regarding your suggestions:
Send body is checked: Yes.
Content type is set to RAW: We tried setting it to JSON and removing the manual Content-Type header as you suggested, but it resulted in the same 400 error. We are using Raw mode to be as close as possible to the cURL command that works.
The core of the issue remains: the cURL command works perfectly, but the n8n node with the same parameters fails.
Updating my previous post. After extensive debugging, we have definitive proof that this is likely a bug in the HTTP Request node’s behavior.
Here is the summary:
1. A cURL command, run from my self-hosted n8n server, works PERFECTLY. It successfully creates a customer and returns a 201 response with the customer’s data.
Working cURL command: curl --request POST --url 'https://app.pennylane.com/api/external/v2/company_customers' --header 'Authorization: Bearer <MY_API_KEY>' --header 'Content-Type: application/json' --header 'Accept: application/json' --data '{"name": "Client Test Monoline","billing_address": {"address": "1 Rue de la Console","postal_code": "75001","city": "Paris","country_alpha2": "FR"}}'
2. The n8n HTTP Request node, configured to be an EXACT replica of the cURL command, fails with a 400 error. The error is "Content-Type" request header must be set to "application/json", even though the header is correctly configured.
I have tried everything:
Using Header Auth and manual Authorization header.
Using Body Content Type: JSON and Raw.
Adding a User-Agent header to mimic cURL.
My final, perfectly configured (but failing) node. All headers, including Content-Type, are present.
Since the cURL command works from the same machine, the issue is not the API, the key, or the network. The issue is with how the n8n node is constructing or sending the request.
Can the n8n team please look into this? Thank you.
Hello, and thank you so much for your help and for providing the node’s code.
Unfortunately, I’m facing a very fundamental issue: I am completely unable to paste or import your code into my n8n instance. I have tried pasting it directly onto the canvas, using the `Ctrl+i` shortcut, and the right-click “Paste” menu, but none of these methods are working for me. As a workaround, I tried to manually configure a new HTTP Request node based on your code with the help of my AI assistant (Gemini), but it still fails with the same error.
To be honest, as a psychologist with very little real coding knowledge, I am at a complete impasse and it’s driving me crazy. My credentials for all my Google tools (Drive, Sheets, Gemini, Docs) work perfectly in n8n, but every attempt to connect to the Pennylane API has been failing for days. The most frustrating part is that we have proven that a `cURL` command, run from my VPS terminal, works perfectly and successfully creates a customer. But the identical request in n8n always fails. I’m truly stuck.
In the Http node , in the right top you can see a button “Import Curl” , paste the Curl command you have there(it will auto-populate the fields), and try again.
Do you have it running localy or in the cloud. It still sounds like an configuration error. Can you share the workflow? Or at least give some screenshots of the nodes you think give the problems so we can try and troubleshoot?
We’ve solved the issue with Gemini. I’m just getting started with APIs, auth headers, JSON, and other programming delights. I made a few beginner mistakes—especially with my API key—but as we say in France, “c’est en forgeant que l’on devient forgeron” : “practice makes perfect.” Your code was really helpful, and I can now access our accounting software from our n8n workflow.