n8n

n8n Database Connection Errors: Complete Troubleshooting Guide

DeviDevs Team
7 min read
#n8n#database#postgresql#mysql#troubleshooting

Database connections are critical for n8n workflows. This guide covers all common database connection errors and their solutions.

Error: ECONNREFUSED - Connection Refused

Symptom:

Error: connect ECONNREFUSED 127.0.0.1:5432
Error: Connection refused to localhost:3306

Cause 1: Database not running

# Check if PostgreSQL is running
sudo systemctl status postgresql
# or for Docker
docker ps | grep postgres
 
# Start PostgreSQL
sudo systemctl start postgresql
# or Docker
docker start postgres-container

Cause 2: Wrong host in Docker network

# docker-compose.yml - Wrong configuration
services:
  n8n:
    environment:
      - DB_POSTGRESDB_HOST=localhost  # ❌ Wrong in Docker
 
  postgres:
    image: postgres:15
 
# Correct configuration
services:
  n8n:
    environment:
      - DB_POSTGRESDB_HOST=postgres  # ✅ Use service name
    depends_on:
      - postgres
 
  postgres:
    image: postgres:15

Cause 3: Firewall blocking port

# Check if port is accessible
nc -zv database-host 5432
 
# Open port (Ubuntu/Debian)
sudo ufw allow 5432/tcp
 
# Check PostgreSQL listening
sudo ss -tlnp | grep 5432

Error: Authentication Failed

Symptom:

Error: password authentication failed for user "n8n"
Error: Access denied for user 'n8n'@'172.18.0.3'
MongoServerError: Authentication failed

Solution 1 - Verify credentials:

# Test PostgreSQL connection manually
psql -h localhost -U n8n -d n8n_db -W
 
# Test MySQL connection
mysql -h localhost -u n8n -p n8n_db
 
# Test MongoDB connection
mongosh "mongodb://n8n:password@localhost:27017/n8n_db"

Solution 2 - Reset user password:

-- PostgreSQL
ALTER USER n8n WITH PASSWORD 'new_password';
 
-- MySQL
ALTER USER 'n8n'@'%' IDENTIFIED BY 'new_password';
FLUSH PRIVILEGES;

Solution 3 - Check authentication method (PostgreSQL):

# Edit pg_hba.conf
sudo nano /etc/postgresql/15/main/pg_hba.conf
 
# Change 'peer' to 'md5' or 'scram-sha-256' for password auth
# host    all    all    0.0.0.0/0    scram-sha-256
 
# Restart PostgreSQL
sudo systemctl restart postgresql

Error: Connection Timeout

Symptom:

Error: Connection timed out after 30000ms
Error: ETIMEDOUT: connection timed out
Error: read ETIMEDOUT

Cause 1: Network latency or firewall

// n8n node configuration - increase timeout
{
  "operation": "executeQuery",
  "connectionTimeout": 60000,  // 60 seconds
  "requestTimeout": 120000     // 2 minutes for query
}

Cause 2: Database under heavy load

-- PostgreSQL: Check active connections
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
 
-- MySQL: Check running queries
SHOW PROCESSLIST;
 
-- Kill long-running queries if needed
-- PostgreSQL
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE duration > interval '5 minutes';

Cause 3: SSL/TLS handshake issues

// n8n PostgreSQL node - disable SSL for local dev
{
  "ssl": false
}
 
// Or configure SSL properly
{
  "ssl": {
    "rejectUnauthorized": false,
    "ca": "-----BEGIN CERTIFICATE-----..."
  }
}

Error: Too Many Connections

Symptom:

Error: too many connections for role "n8n"
Error: FATAL: sorry, too many clients already
Error: Connection pool exhausted

Solution 1 - Increase max connections:

-- PostgreSQL: Check current limit
SHOW max_connections;
 
-- Increase in postgresql.conf
-- max_connections = 200
 
-- MySQL: Check limit
SHOW VARIABLES LIKE 'max_connections';
 
-- Increase
SET GLOBAL max_connections = 200;

Solution 2 - Configure n8n connection pool:

# n8n environment variables
DB_POSTGRESDB_POOL_SIZE=10  # Default is 5

Solution 3 - Monitor and close idle connections:

-- PostgreSQL: Find idle connections
SELECT pid, usename, state, query_start, query
FROM pg_stat_activity
WHERE state = 'idle'
  AND query_start < now() - interval '10 minutes';
 
-- Terminate idle connections
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
  AND query_start < now() - interval '30 minutes';

Error: SSL Connection Required

Symptom:

Error: SSL connection is required
Error: The server does not support SSL connections
FATAL: no pg_hba.conf entry for host with SSL off

Solution 1 - Enable SSL in n8n:

// PostgreSQL node configuration
{
  "ssl": true,
  "sslMode": "require"
}

Solution 2 - Use connection string with SSL:

# n8n environment variable
DATABASE_URL=postgres://user:pass@host:5432/db?sslmode=require

Solution 3 - Provide SSL certificates:

// Node configuration with certificates
{
  "ssl": {
    "ca": "{{ $env.DB_CA_CERT }}",
    "cert": "{{ $env.DB_CLIENT_CERT }}",
    "key": "{{ $env.DB_CLIENT_KEY }}",
    "rejectUnauthorized": true
  }
}

Error: Database Does Not Exist

Symptom:

Error: database "n8n_production" does not exist
Error: Unknown database 'n8n_prod'

Solution - Create database:

-- PostgreSQL
CREATE DATABASE n8n_production;
GRANT ALL PRIVILEGES ON DATABASE n8n_production TO n8n;
 
-- MySQL
CREATE DATABASE n8n_production CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON n8n_production.* TO 'n8n'@'%';
FLUSH PRIVILEGES;

Error: Permission Denied

Symptom:

Error: permission denied for table workflow_entity
Error: INSERT command denied to user 'n8n'

Solution - Grant permissions:

-- PostgreSQL: Grant all on schema
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO n8n;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO n8n;
GRANT USAGE ON SCHEMA public TO n8n;
 
-- For future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON TABLES TO n8n;
 
-- MySQL
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
ON n8n_db.* TO 'n8n'@'%';
FLUSH PRIVILEGES;

Error: Serialization Failure (Deadlock)

Symptom:

Error: could not serialize access due to concurrent update
Error: Deadlock found when trying to get lock

Solution 1 - Implement retry logic:

// Function node with retry
const maxRetries = 3;
let attempt = 0;
 
while (attempt < maxRetries) {
  try {
    // Your database operation
    const result = await $node["Postgres"].execute();
    return result;
  } catch (error) {
    if (error.message.includes('serialize') || error.message.includes('deadlock')) {
      attempt++;
      await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt)));
      continue;
    }
    throw error;
  }
}

Solution 2 - Use advisory locks (PostgreSQL):

-- Acquire lock before critical section
SELECT pg_advisory_lock(12345);
 
-- Your operations here
 
-- Release lock
SELECT pg_advisory_unlock(12345);

Docker-Specific Database Issues

Network configuration:

# docker-compose.yml
version: '3.8'
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
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - n8n-network
    depends_on:
      postgres:
        condition: service_healthy
 
  postgres:
    image: postgres:15
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - n8n-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5
 
networks:
  n8n-network:
    driver: bridge
 
volumes:
  postgres-data:

Debug container networking:

# Check if containers can see each other
docker exec n8n ping postgres
 
# Check DNS resolution
docker exec n8n nslookup postgres
 
# Test connection from n8n container
docker exec n8n nc -zv postgres 5432

Connection String Formats

# PostgreSQL
DATABASE_URL=postgres://user:password@host:5432/database?sslmode=require
 
# MySQL
DATABASE_URL=mysql://user:password@host:3306/database
 
# MongoDB
DATABASE_URL=mongodb://user:password@host:27017/database?authSource=admin
 
# With special characters in password (URL encode)
# Password: p@ss#word! becomes p%40ss%23word%21
DATABASE_URL=postgres://user:p%40ss%23word%21@host:5432/database

Quick Diagnostic Commands

# Test PostgreSQL
PGPASSWORD=password psql -h host -U user -d database -c "SELECT 1"
 
# Test MySQL
mysql -h host -u user -ppassword database -e "SELECT 1"
 
# Test MongoDB
mongosh "mongodb://user:password@host:27017/database" --eval "db.runCommand({ping: 1})"
 
# n8n debug mode
N8N_LOG_LEVEL=debug n8n start

Quick Reference: Connection Errors

| Error | Likely Cause | Quick Fix | |-------|--------------|-----------| | ECONNREFUSED | DB not running | Start database service | | Auth failed | Wrong credentials | Verify user/password | | Timeout | Network/firewall | Check connectivity, increase timeout | | Too many connections | Pool exhausted | Increase max_connections | | SSL required | Security policy | Enable SSL in connection | | Permission denied | Missing grants | GRANT privileges to user |

Need Database Integration Help?

Complex database workflows require careful planning. Our team offers:

  • n8n workflow optimization
  • Database performance tuning
  • High-availability configurations
  • Migration and ETL pipelines

Get expert help

Weekly AI Security & Automation Digest

Get the latest on AI Security, workflow automation, secure integrations, and custom platform development delivered weekly.

No spam. Unsubscribe anytime.