
Step by Step Guide to solve n8n SSL Certificate Errors
Who this is for: Developers or DevOps engineers running n8n in a development, staging, or internal‑only production environment that must use self‑signed TLS certificates. We cover this in detail in the n8n Installation Errors Guide
If n8n aborts with “certificate not trusted” on start‑up, add the self‑signed CA to the OS trust store or point Node to it via NODE_EXTRA_CA_CERTS, then configure n8n’s TLS variables (N8N_TLS_CERTIFICATE, N8N_TLS_KEY). Restart n8n and the error disappears.
Quick Fix: Works for 90% of Cases
If n8n is throwing self-signed certificate in chain on startup, run this before starting n8n:
export NODE_EXTRA_CA_CERTS=/path/to/your/ca.crt n8n start
Not working? Your error might be node-level (HTTP Request node, Postgres, SMTP) — jump to the right section using the diagnosis guide below.
Which SSL Error Do You Have? (Find Your Fix Fast)
Not all n8n SSL errors are the same. Find your exact error in the table and jump to the right fix:
| Error Message | Where It Appears | Go To |
|---|---|---|
self-signed certificate in chain |
Terminal / n8n startup | Sections 2 & 3 |
unable to verify the first certificate |
Terminal / n8n startup | Sections 2 & 3 |
SELF_SIGNED_CERT_IN_CHAIN on HTTP Request node |
Workflow execution log | Section 5b |
self-signed certificate during npm install -g n8n |
Terminal during install | Section 5c |
| SSL error on Postgres / Supabase / MySQL node | Workflow execution log | Section 5d |
| SSL error on SMTP / Email Send node | Workflow execution log | Section 5e |
If you’re on n8n v1.42.0 or newer running in Docker, skip straight to Section 4b — the /opt/custom-certificates method requires no environment variables at all.
1. Why n8n Throws “certificate not trusted”
If you encounter any proxy configuration error n8n resolve them before continuing with the setup.
What you’ll see – n8n exits with errors such as:
Error: self‑signed certificate in chain Error: unable to verify the first certificate
Root cause – Node.js cannot verify the TLS chain because the CA that signed the server’s certificate is missing from its trust store.
EEFA: Self‑signed certificates are acceptable only for internal/dev use. Production‑grade deployments should use a trusted CA (Let’s Encrypt, commercial CA) to avoid MITM risks.
2. Import the Self‑Signed CA into the Host Trust Store
If you encounter any docker compose configuration error n8n resolve them before continuing with the setup.
2.1 Linux (Debian/Ubuntu)
Copy the CA bundle and update the system store.
# Copy the CA file sudo cp my-ca.crt /usr/local/share/ca-certificates/
# Refresh the trust store sudo update-ca-certificates
2.2 macOS
Add the CA to the system keychain.
sudo security add-trusted-cert \ -d -r trustRoot -k /Library/Keychains/System.keychain \ my-ca.crt
2.3 Windows (PowerShell)
Import the CA into the Local Machine Trusted Root store.
Import-Certificate -FilePath .\my-ca.crt ` -CertStoreLocation Cert:\LocalMachine\Root
Verification – Run the following to confirm the CA is recognized:
openssl s_client -connect <host>:443 -CAfile my-ca.crt
You should see Verify return code: 0 (ok).
3. Tell Node.js to Trust the Self‑Signed CA (OS‑store alternative)
Set NODE_EXTRA_CA_CERTS before starting n8n.
3.1 Bash / Linux / macOS
export NODE_EXTRA_CA_CERTS=/path/to/my-ca.crt
3.2 Windows CMD
set NODE_EXTRA_CA_CERTS=C:\path\to\my-ca.crt
3.3 PowerShell
$env:NODE_EXTRA_CA_CERTS="C:\path\to\my-ca.crt"
EEFA: Never use
NODE_TLS_REJECT_UNAUTHORIZED=0in production—it disables verification entirely.
4. Configure n8n TLS Termination (Self‑Signed Cert)
4.1 Docker Compose – Service Definition
version: '3.8'
services:
n8n:
image: n8nio/n8n
ports:
- "443:5678"
4.2 Docker Compose – TLS & CA Environment
environment:
- N8N_TLS_CERTIFICATE=/certs/server.crt
- N8N_TLS_KEY=/certs/server.key
- NODE_EXTRA_CA_CERTS=/certs/my-ca.crt # optional if OS store used
4.3 Docker Compose – Read‑Only Volume Mount
volumes:
- ./certs:/certs:ro # mount certs read‑only
Tip: Keeping the
certsdirectory read‑only (:ro) prevents accidental modification from inside the container.
4.4 Stand‑Alone npm / yarn Installation – .env File
Create an .env file in the n8n root:
N8N_TLS_CERTIFICATE=/opt/n8n/certs/server.crt N8N_TLS_KEY=/opt/n8n/certs/server.key
If you rely on NODE_EXTRA_CA_CERTS:
NODE_EXTRA_CA_CERTS=/opt/n8n/certs/my-ca.crt
Start n8n:
npm run start # or simply: n8n start
4.5 Windows Service – Inline Environment
set N8N_TLS_CERTIFICATE=C:\n8n\certs\server.crt set N8N_TLS_KEY=C:\n8n\certs\server.key set NODE_EXTRA_CA_CERTS=C:\n8n\certs\my-ca.crt n8n start
4b. Mount Certificates via /opt/custom-certificates (n8n v1.42.0+ — Easiest Docker Method)
If you’re running n8n v1.42.0 or newer in Docker, this is the cleanest approach. You don’t need any environment variables — n8n automatically detects and trusts every .crt file placed in the /opt/custom-certificates directory on startup.
Step 1 — Create a local folder and copy your CA file into it
mkdir -p ./pki cp my-ca.crt ./pki/
Step 2 — Mount the folder into your docker-compose.yml
services:
n8n:
image: n8nio/n8n
ports:
- "443:5678"
volumes:
- n8n_data:/home/node/.n8n
- ./pki:/opt/custom-certificates:ro
Step 3 — Fix file permissions (run once after first start)
docker exec n8n chmod -R 644 /opt/custom-certificates docker restart n8n
Step 4 — Confirm n8n loaded the certificate
docker logs n8n 2>&1 | grep -i cert
You should see a line referencing your certificate file. If you see nothing, the file either has wrong permissions or is not valid PEM format.
Most common failure: Container starts but SSL errors persist even after mounting. This almost always means n8n can’t read the files because they’re owned by root inside the container. The
chmod 644in Step 3 fixes this.If it still fails, verify your file is valid PEM format:
openssl x509 -in ./pki/my-ca.crt -text -noout
Note: This method handles certificates for outbound connections made by n8n’s core. If your workflows make HTTPS calls via the HTTP Request node that still fail, also set
NODE_EXTRA_CA_CERTSpointing to the same CA file (see Section 3).
5. Verify the TLS Configuration
5.1 Curl Test (skip hostname verification)
curl -k https://localhost:443/api/health
Expected output – {"status":"ok","version":"X.Y.Z"} (the -k flag bypasses hostname validation but confirms the endpoint is reachable).
5.2 Curl Test (use the CA – no -k)
curl --cacert my-ca.crt https://localhost:443/api/health
Expected output – Same JSON response without -k, proving the CA is trusted.
5.3 n8n HTTP Request Node
Create a simple HTTP Request node targeting https://localhost:443/api/health. A successful execution (no “self‑signed certificate” error) confirms the in‑process trust chain.
| Verification Method | Expected Result |
|---|---|
| curl -k (skip verification) | 200 OK (does not prove trust) |
| curl –cacert my-ca.crt … | 200 OK without -k |
| n8n HTTP Request node | No TLS error in execution log |
5b. Fix SSL Errors Inside the HTTP Request Node
If n8n starts fine but you get self-signed certificate in chain when a workflow runs an HTTP Request node, the issue is different — n8n’s internal request engine doesn’t automatically inherit your OS trust store. You need to fix it at the process level.
Fix 1 — Per-node toggle (quick workaround, not recommended for production):
In the HTTP Request node, click Options at the bottom → enable Ignore SSL Issues. This bypasses verification for that specific node only. Use this temporarily to confirm SSL is the actual problem.
Fix 2 — NODE_EXTRA_CA_CERTS (correct long-term fix):
Set NODE_EXTRA_CA_CERTS in your environment before n8n starts (see Section 3 above). This makes every HTTP Request node in every workflow trust your CA automatically — no per-node toggle needed.
Why does this happen even after fixing the startup error? The OS trust store fix (Section 2) makes your system trust the CA. But n8n’s HTTP engine reads
NODE_EXTRA_CA_CERTSat process startup — not the OS store. If you only did Section 2 and skipped Section 3, startup works but in-workflow requests still fail.
5c. Fix SSL Errors During npm install -g n8n
If you get a certificate error during the n8n installation itself (not at runtime), it means npm can’t reach the registry over your corporate or self-signed proxy.
Step 1 — Install with strict-ssl disabled (temporary):
npm install -g n8n --strict-ssl=false
Step 2 — Re-enable strict SSL immediately after:
npm config set strict-ssl true
Step 3 — Register your CA with npm permanently so future installs don’t need the flag:
npm config set cafile /path/to/my-ca.crt
5d. Fix SSL Errors on Postgres / Supabase / MySQL Nodes
When a database node throws an SSL error, the fix lives inside the credential — not the server or environment config.
For Postgres / MySQL:
- Go to Credentials → open your Postgres or MySQL credential
- Find the SSL section
- Set SSL to
alloworrequire - Under CA Certificate, paste the full contents of your
my-ca.crtfile - Save and re-run the workflow
For Supabase:
Supabase’s connection pooler (port 6543) uses a self-signed certificate in some regions. In your Postgres credential, set the CA Certificate field to Supabase’s root CA — downloadable from your Supabase project under Settings → Database → SSL Certificate.
5e. Fix SSL Errors on SMTP / Email Send Nodes
Corporate SMTP servers (Microsoft Exchange, internal mail relays) frequently use self-signed or internally-signed certificates. If your Email Send node fails with an SSL error:
- In the Email Send node credentials, confirm SSL/TLS is set to
STARTTLSorSSL/TLSdepending on what your mail server requires (ask your sysadmin if unsure) - If the error continues, set
NODE_EXTRA_CA_CERTSto your internal mail server’s CA certificate path (same method as Section 3) and restart n8n - For completely isolated internal environments with no external exposure, you can set
NODE_TLS_REJECT_UNAUTHORIZED=0as a last resort — but only in internal-only setups. Never in production.
6. Troubleshooting Checklist
| ✅ Done? | Step |
|---|---|
| ☐ | CA file is PEM (-----BEGIN CERTIFICATE-----). |
| ☐ | NODE_EXTRA_CA_CERTS points to the exact CA file (not a directory). |
| ☐ | N8N_TLS_CERTIFICATE and N8N_TLS_KEY paths are readable by the n8n process. |
| ☐ | Docker volume mounts are ro and files exist inside the container (docker exec <id> ls /certs). |
| ☐ | No conflicting env vars (e.g., NODE_TLS_REJECT_UNAUTHORIZED). |
| ☐ | After any change, restart the n8n service/container (not just reload). |
| ☐ | Review logs (docker logs n8n or journalctl -u n8n) for lingering TLS errors. |
If a step fails, logs typically surface the missing file or a verification code such as UNABLE_TO_VERIFY_LEAF_SIGNATURE or SELF_SIGNED_CERT_IN_CHAIN.
7. Production‑Ready Alternatives
| Scenario | Recommended Action |
|---|---|
| Public‑facing n8n instance | Use a trusted CA (Let’s Encrypt) and terminate TLS at a reverse proxy (Traefik, Nginx). |
| Multi‑node Kubernetes deployment | Store certificates in a Secret, mount into the pod, and set NODE_EXTRA_CA_CERTS via a ConfigMap. |
| High‑security environment | Enable mTLS: add N8N_TLS_CLIENT_CERTIFICATE and N8N_TLS_CLIENT_KEY variables, enforce client verification. |
Frequently Asked Questions
What does “self-signed certificate in chain” mean in n8n?
It means Node.js tried to verify a TLS certificate during an HTTPS connection but couldn’t find a trusted Certificate Authority (CA) that signed it. The certificate exists and is technically valid, but Node.js doesn’t recognise the entity that issued it. The fix is to tell Node.js about your CA using NODE_EXTRA_CA_CERTS or by importing the CA into your OS trust store — not to disable verification entirely.
Should I use NODE_TLS_REJECT_UNAUTHORIZED=0 to fix n8n SSL errors?
No. Setting NODE_TLS_REJECT_UNAUTHORIZED=0 disables all TLS certificate verification globally across the entire n8n process. This silences the error but means n8n will accept any certificate — including fraudulent ones from attackers — making it vulnerable to man-in-the-middle attacks. Use NODE_EXTRA_CA_CERTS instead. It keeps verification fully enabled while adding your specific CA to the trusted list.
Does n8n support custom CA certificates natively?
Yes, since n8n v1.42.0. Mount a folder containing your .crt files to /opt/custom-certificates inside the Docker container. n8n automatically loads all valid PEM certificates in that directory at startup. No environment variables are required. See Section 4b for the full setup.
How do I fix SSL errors in n8n running in Docker?
Two approaches: (1) Set NODE_EXTRA_CA_CERTS=/certs/my-ca.crt in your docker-compose.yml environment block and mount the certs folder as a volume. (2) On n8n v1.42.0+, mount your CA file to /opt/custom-certificates — n8n auto-loads it on startup. Method 2 is cleaner because it requires no environment variable changes and works across all n8n versions that support it.
What is NODE_EXTRA_CA_CERTS and how does it work in n8n?
NODE_EXTRA_CA_CERTS is a Node.js environment variable that points to an additional CA certificate file. When set before n8n starts, Node.js appends that CA to its built-in trust list without replacing any existing trusted CAs. For n8n, this means all outgoing HTTPS connections — workflow HTTP Request nodes, webhooks, external API calls — will trust certificates signed by your CA.
Why does my n8n HTTP Request node still show SSL errors after fixing the startup error?
This is one of the most common points of confusion. Importing the CA into your OS trust store (Section 2) fixes the startup error because n8n’s startup process respects the OS store. But the HTTP Request node’s internal engine reads NODE_EXTRA_CA_CERTS at process startup — not the OS store. If you only did Section 2 and skipped Section 3, startup works but in-workflow HTTPS requests still fail. The fix is to also set NODE_EXTRA_CA_CERTS explicitly in your environment and restart n8n.
Conclusion
Adding the self‑signed CA to the host trust store or exposing it via NODE_EXTRA_CA_CERTS resolves the “certificate not trusted” error by giving Node.js the chain it needs to validate TLS connections. Coupled with proper N8N_TLS_CERTIFICATE and N8N_TLS_KEY settings, n8n starts cleanly and can communicate securely with both internal services and external APIs. For production workloads, migrate to a trusted CA and consider proxy‑based termination or mTLS to meet higher security requirements.



