Error : [Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string] Self-host n8n with Traefik, Postgres with docker

Hi folks,

I am trying to self-host n8n with Traefik and Postgres using docker-compose. I couldn’t find any tutorials for this combination and I am doing this for the first time. I cobbled up different compose files from git and got the docker containers working (atleast did for Traefik and Postgres) but the n8n container is throwing an error. Would really appreciate if someone can help provide some insight to why I am seeing this error? Thank you in advance

Error on docker-compose up

postgres-1  | 
postgres-1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres-1  | 
postgres-1  | 2024-09-10 09:03:11.182 UTC [1] LOG:  starting PostgreSQL 16.4 (Debian 16.4-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.
2.0, 64-bit
postgres-1  | 2024-09-10 09:03:11.183 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres-1  | 2024-09-10 09:03:11.183 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres-1  | 2024-09-10 09:03:11.187 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres-1  | 2024-09-10 09:03:11.197 UTC [28] LOG:  database system was shut down at 2024-09-10 08:54:42 UTC
postgres-1  | 2024-09-10 09:03:11.207 UTC [1] LOG:  database system is ready to accept connections
n8n-1       | User settings loaded from: /home/node/.n8n/config
n8n-1       | Last session crashed
n8n-1       | Initializing n8n process
n8n-1       | Error: There was an error initializing DB
n8n-1       | Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string

Here are the files

docker-compose.yml

version: "3.7"

volumes:
  traefik_data:
    external: true
  n8n_data:
    external: true
  db_storage:
  n8n_storage:

services:
  postgres:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB
    volumes:
      - db_storage:/var/lib/postgresql/data
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 5s
      timeout: 5s
      retries: 10

  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    links:
      - postgres
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
     volumes:
      - n8n_data:/home/node/.n8n
    
    depends_on:
      postgres:
        condition: service_healthy

.env

POSTGRES_USER=rootUser
POSTGRES_PASSWORD=rootPassword
POSTGRES_DB=n8n

# The top level domain to serve from
DOMAIN_NAME=sandeepmallareddy.com

# The subdomain to serve from
SUBDOMAIN=aut0mati0n

# DOMAIN_NAME and SUBDOMAIN combined decide where n8n will be reachable from
# above example would result in: https://n8n.example.com

# Optional timezone to set which gets used by Cron-Node by default
# If not set New York time will be used
GENERIC_TIMEZONE=Europe/Berlin

# The email address to use for the SSL certificate creation
[email protected]

init-data.sh

#!/bin/bash
set -e;


if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
		CREATE USER ${POSTGRES_NON_ROOT_USER} WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
		GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_NON_ROOT_USER};
		GRANT CREATE ON SCHEMA public TO ${POSTGRES_NON_ROOT_USER};
	EOSQL
else
	echo "SETUP INFO: No Environment variables given!"
fi

Information on your n8n setup

  • n8n version: 1.57.0
  • Database (default: SQLite): Postgres
  • n8n EXECUTIONS_PROCESS setting (default: own, main): own
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: Linux (Ubuntu 22.04)

Hello @Sandeep_Mallareddy ,

It has been a while we have not heard from you here. Welcome back!

I had a quick check on your issue and while the error is straight forward, it does not tip what exactly is causing it: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string.

In order to attempt to narrow down on what is causing it, I have the following considerations:

In your docker file I see POSTGRES_PASSWORD which is coming from ENV * POSTGRES_PASSWORD=rootPassword.

  • Is the root password surrounded by quotes ‘’?
  • Can you test by hardcoding directky in the yml file with POSTGRES_PASSWORD: ‘yourpassword’
  • Does the password contain any special character like $? If so you may need to escape it. You can test with a more generic password to check if it works.

These would be my initial suggestions.

Hi Flavio,

Thank you for your prompt response, and I apologize for not replying sooner. I tried everything you suggested (using a generic password, escaping special characters, and hard-coding the credentials in the YAML file), but the problem persisted. As a result, I abandoned these efforts and switched to using n8n through npm. Perhaps when I’m in a less mission-critical situation, I’ll try again. As always, thank you for your support in this community. Have a great time ahead!

Regards,
Sandeep