Fix Database Connection Errors in n8n: 5 Steps

Step by Step Guide to solve n8n Database Connection Errors

Who this is for: Developers and DevOps engineers deploying n8n with an external PostgreSQL or MySQL/MariaDB instance, who need to diagnose and resolve connection‑related failures in production or staging environments. We cover this in detail in the n8n Installation Errors Guide.


Quick Diagnosis

  1. Verify DB credentials in .env (or Docker Compose).
  2. Confirm the DB host/port is reachable from the n8n container (nc -z <host> <port>).
  3. Add ?sslmode=require for PostgreSQL only when TLS is enforced.
  4. Restart n8n after any change: docker compose restart n8n or npm run start.
  5. If the error persists, inspect the logs (docker logs n8n or npm run start) for “Database connection error” and apply the relevant fix from the tables below.

1. Why n8n Fails to Connect to a Database

If you encounter any memory limit error n8n resolve them before continuing with the setup.

Error excerpt Typical cause
Authentication failed for user Wrong username/password or missing role
connect ECONNREFUSED DB host/port unreachable (network or firewall)
SSL error: certificate verify failed SSL required but not configured, or self‑signed cert without rejectUnauthorized: false
ER_BAD_DB_ERROR Database name does not exist
SequelizeConnectionError Version mismatch (e.g., MySQL 5.6 vs Sequelize 6)
Quick test Command
Verify credentials psql -U <user> -h <host> -p <port>
Check reachability nc -z <host> <port>
List databases (MySQL) SHOW DATABASES;
Verify DB version compatibility Consult n8n docs for supported driver versions

EEFA Note: Never store production passwords in plain text. Use a secret manager (Docker secrets, Kubernetes Secrets, or a restricted‑permission .env).


2. Configuring PostgreSQL for n8n

If you encounter any n8n startup failure error resolve them before continuing with the setup.

2.1 Required environment variables

Core settings

DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres.example.com
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=••••••••

Optional SSL

DB_POSTGRESDB_SSL=true
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=false   # only for self‑signed certs

2.2 Docker‑Compose – n8n service

services:
  n8n:
    image: n8nio/n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - DB_POSTGRESDB_SSL=true               # remove if not needed
    depends_on:
      - postgres

2.3 Docker‑Compose – PostgreSQL service

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n_user
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

2.4 Step‑by‑step verification

  1. Create the user – run inside the PostgreSQL container
    psql -U postgres -c "CREATE USER n8n_user WITH PASSWORD 'StrongPass!';"
    
  2. Create the database – still inside the container
    psql -U postgres -c "CREATE DATABASE n8n OWNER n8n_user;"
    
  3. Grant privileges on the public schema
    psql -U postgres -d n8n -c "GRANT ALL PRIVILEGES ON SCHEMA public TO n8n_user;"
    
  4. Test connectivity from the n8n container
    docker exec -it <n8n_container> sh -c "
      apk add --no-cache postgresql-client &&
      pg_isready -h postgres -p 5432 -U n8n_user
    "
    
  5. Restart n8n and watch the logs for database messages
    docker compose restart n8n
    docker logs -f n8n | grep "Database"
    

EEFA Warning: Do not grant SUPERUSER to the n8n DB user. It expands the attack surface and can cause accidental schema changes.


3. Configuring MySQL / MariaDB for n8n

3.1 Required environment variables

Core settings

DB_TYPE=mysqldb
DB_MYSQLDB_HOST=mysql.example.com
DB_MYSQLDB_PORT=3306
DB_MYSQLDB_DATABASE=n8n
DB_MYSQLDB_USER=n8n_user
DB_MYSQLDB_PASSWORD=••••••••

Optional TLS

DB_MYSQLDB_SSL=true
DB_MYSQLDB_SSL_REJECT_UNAUTHORIZED=false   # self‑signed only

3.2 Docker‑Compose – n8n service

services:
  n8n:
    image: n8nio/n8n
    environment:
      - DB_TYPE=mysqldb
      - DB_MYSQLDB_HOST=mysql
      - DB_MYSQLDB_PORT=3306
      - DB_MYSQLDB_DATABASE=n8n
      - DB_MYSQLDB_USER=n8n_user
      - DB_MYSQLDB_PASSWORD=${MYSQL_PASSWORD}
      - DB_MYSQLDB_SSL=true               # remove if not needed
    depends_on:
      - mysql

3.3 Docker‑Compose – MySQL service

  mysql:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_DATABASE: n8n
      MYSQL_USER: n8n_user
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - mysqldata:/var/lib/mysql
volumes:
  mysqldata:

3.4 Step‑by‑step verification

  1. Create the database
    CREATE DATABASE n8n CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
  2. Create the user and grant privileges
    CREATE USER 'n8n_user'@'%' IDENTIFIED BY 'StrongPass!';
    GRANT ALL PRIVILEGES ON n8n.* TO 'n8n_user'@'%';
    FLUSH PRIVILEGES;
    
  3. Test connectivity from the n8n container
    docker exec -it <n8n_container> sh -c "
      apk add --no-cache mysql-client &&
      mysql -h mysql -P 3306 -u n8n_user -p
    "
    
  4. Verify TLS (optional) – if DB_MYSQLDB_SSL=true, ensure a valid server certificate is presented, or set rejectUnauthorized=false only for development.

EEFA Note: MySQL 8 defaults to caching_sha2_password. n8n’s Sequelize driver supports it, but older drivers may require mysql_native_password. The command line above forces that compatibility when you encounter authentication errors.


4. Migrating an Existing n8n Database

4.1 PostgreSQL → PostgreSQL

Step Command
Dump source DB pg_dump -Fc -U old_user olddb > dump.sql
Restore to target pg_restore -d newdb -U new_user dump.sql

4.2 MySQL → MySQL

Step Command
Dump source DB mysqldump -u root -p olddb > dump.sql
Import to target mysql -u root -p newdb < dump.sql

4.3 PostgreSQL → MySQL (cross‑type)

Tool Command
pg2mysql (open‑source) pg2mysql -h pg_host -U pg_user -d pgdb -t mysql_host -u mysql_user -p mysql_pass -d mysqldb
n8n built‑in migration n8n migration:postgres-to-mysql (follow CLI prompts)

4.4 Post‑migration sanity checks

  • Row‑count comparison – PostgreSQL
    docker exec -it postgres psql -U n8n_user -d n8n -c "SELECT COUNT(*) FROM workflow;"
    
  • Row‑count comparison – MySQL
    docker exec -it mysql mysql -u n8n_user -p -e "SELECT COUNT(*) FROM workflow;" n8n
    

– Verify that the workflow table row count matches the source.
– Run a quick workflow in the UI to confirm execution.

EEFA Warning: Always back up the source DB before migration. Test the migration in a staging environment first; production migrations can lock tables and cause downtime.


5. Debugging n8n Database Errors in Real‑Time

  1. Enable verbose logging – add to .env
    LOG_LEVEL=debug
    
  2. Tail the logs while reproducing the error
    docker logs -f n8n | grep -i "database"
    
  3. Inspect the Sequelize error object (shown in the log). It contains original.code, original.sqlstate, and original.message. Use these fields to pinpoint the exact driver error.

5.1 Common Sequelize error codes

original.code Meaning Fix
28P01 (Postgres) Invalid password Re‑enter DB_POSTGRESDB_PASSWORD
ECONNREFUSED Host unreachable Check firewall / Docker network
ER_ACCESS_DENIED_ERROR (MySQL) User lacks privileges Grant ALL on the n8n schema
ETIMEDOUT Connection timeout Increase DB_TIMEOUT (default 5000 ms)

6. Frequently Asked Questions

  • Q1. Can I use SQLite for production?
    A: SQLite is only for local testing. Production workloads need PostgreSQL or MySQL for concurrency and durability.
  • Q2. Do I need to set DB_MAX_CONNECTIONS?
    A: n8n defaults to 10. Increase only if you see “Too many connections” in DB logs, and your DB plan supports it.
  • Q3. Why does n8n crash after a DB password change?
    A: The environment variable is cached in the running container. Restart the container after any credential change.
  • Q4. How to enable TLS for PostgreSQL in Docker?
    1. Mount the server certificate and key into the container (example mount in docker-compose.yml).
    2. Add the following variables:
      DB_POSTGRESDB_SSL=true
      DB_POSTGRESDB_SSL_CA=/certs/ca.crt
      
    3. Reference the mount path in docker-compose.yml under volumes.

All configuration examples assume a Unix‑like environment. Adjust paths and package managers accordingly for Windows.

Leave a Comment

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