Knowledgebase

Common n8n Errors on a Self-Hosted Server and How to Fix Them

Most errors on a self-hosted n8n server have one of a few causes: the Docker container is not running, the reverse proxy or HTTPS settings are wrong, the server is short on memory or disk, or an environment variable such as WEBHOOK_URL, GENERIC_TIMEZONE or N8N_ENCRYPTION_KEY is missing or wrong. The fix is usually to read the container logs, correct the variable in your compose or .env file, and recreate the container with docker compose up -d. This guide is organised by symptom and applies to n8n running in Docker on Ubuntu 22.04 or 24.04, including Cloudesta n8n hosting and n8n you installed yourself on a Cloud VPS.

Prerequisites

  • SSH access as root or a sudo user.
  • n8n running with Docker Compose v2 (the docker compose command).
  • A recent backup of the n8n data volume before you change anything.

Run all commands from the directory that contains your docker-compose.yml. If you do not know where it is, find the container name with docker ps and ask Docker for the directory. The commands in this guide assume the service and container are both called n8n. Replace that name if yours is different.

docker ps --format '{{.Names}}  {{.Image}}  {{.Status}}'
docker inspect n8n --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
After you edit docker-compose.yml or .env, run docker compose up -d. A plain docker compose restart does not load new environment variables.

1. Why is my n8n page not loading?

Start by checking whether the container is running and whether n8n answers locally.

docker compose ps
docker compose logs --tail=100 n8n
curl -s http://127.0.0.1:5678/healthz
  • The container is stopped or restarting: read the logs and see section 6.
  • /healthz returns {"status":"ok"} but the site does not load: the problem is in the reverse proxy, DNS or firewall. Check the proxy with sudo nginx -t and sudo systemctl status nginx (or the Caddy or Traefik equivalent). Confirm that your domain resolves to the server IP.
  • Check the firewall:
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Ports published by Docker bypass UFW rules. If n8n sits behind a proxy, bind it to localhost only, using "127.0.0.1:5678:5678" under ports:, so that port 5678 is not exposed to the internet.

2. How do I fix "Your n8n server is configured to use a secure cookie"?

This message appears when you open n8n over plain HTTP, for example http://203.0.113.10:5678. The correct fix is to serve n8n over HTTPS through a reverse proxy with a valid certificate, then set these variables:

N8N_HOST=n8n.example.com
N8N_PROTOCOL=https
N8N_PROXY_HOPS=1

For a short test on a private network only, you can set N8N_SECURE_COOKIE=false. Do not leave this setting on a server that is reachable from the internet.

3. Why are my n8n webhooks not firing?

  • Wrong URL shown in the Webhook node. If the node shows localhost:5678, set the public URL and recreate the container: WEBHOOK_URL=https://n8n.example.com/
  • Workflow inactive. Production URLs (/webhook/...) only work while the workflow is activated. Test URLs (/webhook-test/...) only work while you are listening in the editor.
  • Proxy problems. The proxy must pass the original host and protocol headers. For the editor to stay connected, it must also allow WebSocket upgrades. A minimal Nginx block looks like this:
location / {
    proxy_pass http://127.0.0.1:5678;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
}

To test a webhook from outside the server, send a request to it with curl -X POST https://n8n.example.com/webhook/your-path.

4. Why do executions fail with memory errors or run slowly?

Messages such as "JavaScript heap out of memory" or "n8n may have run out of memory" mean a workflow handled more data than the available RAM allows. Check current usage first:

free -h
docker stats --no-stream

Then work through these fixes:

  • Reduce data per run. Process large data sets in batches with the Loop Over Items node, and avoid passing large binary files between nodes.
  • Raise the Node.js heap limit. Keep it below the server's RAM, for example NODE_OPTIONS=--max-old-space-size=2048.
  • Limit parallel runs. For example, N8N_CONCURRENCY_PRODUCTION_LIMIT=5 caps how many production executions run at the same time.
  • Keep less execution history:
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168
EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none

EXECUTIONS_DATA_MAX_AGE is measured in hours, so 168 keeps one week of history. If workflows still run out of memory after these changes, the server needs more RAM. Plan upgrades are done by opening a support ticket.

5. What do I do when the database grows or the disk is full?

A full disk causes n8n to fail in odd ways, for example saves that do not stick or SQLite "disk I/O" errors. Find out what is using the space:

df -h
docker system df
sudo du -sh /var/lib/docker/volumes/* | sort -h | tail
sudo journalctl --vacuum-size=200M
docker image prune -f

Execution history is usually the main cause, so enable the pruning settings from section 4. Pruning frees rows inside SQLite but does not shrink the file itself. Add DB_SQLITE_VACUUM_ON_STARTUP=true once and recreate the container to compact the file.

To stop container logs from growing without limit, add this to /etc/docker/daemon.json, then run sudo systemctl restart docker:

{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }

The log limit only applies to containers created after the change, so run docker compose up -d --force-recreate afterwards.

6. Why is n8n stuck in a restart loop after an update?

Run docker compose logs --tail=200 n8n and look for one of these three causes:

  • Permission denied on /home/node/.n8n. n8n runs as user ID 1000. If you use a bind mount, fix the ownership with sudo chown -R 1000:1000 ./n8n_data (replace with your folder).
  • Mismatching encryption keys. The N8N_ENCRYPTION_KEY environment variable no longer matches the key stored in the data folder. Restore the original key (see Common problems below).
  • Database migration error. Restore your backup and pin the previous version, for example image: docker.n8n.io/n8nio/n8n:1.xx.x. Then review the release notes before upgrading again.
Newer n8n versions change the database during migrations. Rolling back the image without restoring the matching data backup can leave n8n unable to start.

7. How do I collect logs for a support ticket?

docker compose ps > n8n-report.txt
docker compose exec n8n n8n --version >> n8n-report.txt
docker compose logs --no-color --tail=500 n8n >> n8n-report.txt 2>&1
df -h >> n8n-report.txt; free -h >> n8n-report.txt

For more detail, set N8N_LOG_LEVEL=debug temporarily and reproduce the problem. Before you attach n8n-report.txt, remove any passwords, API keys or tokens from it.

Verify it works

  • docker compose ps shows n8n as Up, not Restarting.
  • curl -s https://n8n.example.com/healthz returns {"status":"ok"}.
  • The editor loads over HTTPS without the secure cookie warning.
  • An active test workflow with a Webhook node responds to an external curl request, and the run appears under Executions.

Common problems

ECONNREFUSED when calling a local service

Inside the container, localhost means the n8n container itself, not the server. Use the Compose service name instead, for example http://postgres:5432. To reach something running directly on the host, add extra_hosts: ["host.docker.internal:host-gateway"] to the n8n service and call http://host.docker.internal:PORT.

ENOTFOUND or EAI_AGAIN DNS errors from nodes

Test name resolution from inside the container:

docker compose exec n8n node -e "require('dns').lookup('api.example.com',(e,a)=>console.log(e||a))"

If the lookup fails inside the container but works on the host, add dns: ["1.1.1.1", "8.8.8.8"] to the n8n service and recreate it.

Schedule Trigger runs at the wrong hour

Set both GENERIC_TIMEZONE=Africa/Cairo and TZ=Africa/Cairo (use your own zone), then recreate the container. Also check the workflow's own timezone under Workflow settings, because that setting overrides the server default.

Credentials "could not be decrypted" after moving servers

The new server is using a different encryption key from the one that encrypted your credentials. On the old server, read the original key:

docker compose exec n8n cat /home/node/.n8n/config

Set the same value as N8N_ENCRYPTION_KEY on the new server, then recreate the container. Without the original key, the stored credentials cannot be recovered and must be re-entered.

Need help? Open a ticket at https://cloudesta.com/submitticket.php and attach your n8n-report.txt. Requests that only Cloudesta can carry out, such as plan upgrades, rescue mode, OS reinstalls and IP changes, are also handled by ticket. More guides are available in the knowledgebase.

Frequently asked questions

Where do I set n8n environment variables?

Set them in the environment: section of docker-compose.yml or in the .env file next to it. After saving, run docker compose up -d so the container is recreated with the new values.

Is it safe to set N8N_SECURE_COOKIE=false?

Only for short tests on a private network. On a public server, use HTTPS through a reverse proxy instead.

Will pruning executions delete my workflows?

No. Pruning removes only past execution records. Workflows and credentials are not touched.

Was this answer helpful?

0 Users Found This Useful

Powered by WHMCompleteSolution