Fix 3 SSL Certificate Errors in n8n Before Workflows Break


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=0 in 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 certs directory 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 644 in 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_CERTS pointing 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_CERTS at 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:

  1. Go to Credentials → open your Postgres or MySQL credential
  2. Find the SSL section
  3. Set SSL to allow or require
  4. Under CA Certificate, paste the full contents of your my-ca.crt file
  5. 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:

  1. In the Email Send node credentials, confirm SSL/TLS is set to STARTTLS or SSL/TLS depending on what your mail server requires (ask your sysadmin if unsure)
  2. If the error continues, set NODE_EXTRA_CA_CERTS to your internal mail server’s CA certificate path (same method as Section 3) and restart n8n
  3. For completely isolated internal environments with no external exposure, you can set NODE_TLS_REJECT_UNAUTHORIZED=0 as 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.

Leave a Comment

Your email address will not be published. Required fields are marked *