n8n SQLite cannot Open Database

Step by Step Guide to solve n8n SQLite cannot open database

 

Who this is for : Developers or DevOps engineers running n8n in containers or on‑premises who encounter SQLITE_CANTOPEN at startup or during workflow execution. For a complete guide on managing SQLite in n8n, including errors, performance, and migration, check out our n8n SQLite pillar guide.

Quick Diagnosis

Symptom Most common cause One‑line fix
Error: SQLITE_CANTOPEN: unable to open database file SQLite file missing or path wrong Create the file or set an absolute path in N8N_DB_SQLITE_DATABASE_FILE.
Same error on start‑up (Docker) Volume not mounted or permissions 0 / 600 Mount the host directory and run chmod 660 /data/database.sqlite && chown 1000:1000 /data/database.sqlite.
Same error after a restart SELinux/AppArmor blocking access Add a policy rule or disable the security module for the n8n container.

Quick actionable fix – run these three commands on the host before (re)starting n8n:

# 1. Ensure the file exists (creates empty DB if missing)
touch /home/n8n/data/database.sqlite

# 2. Give n8n read/write rights
chmod 660 /home/n8n/data/database.sqlite
chown 1000:1000 /home/n8n/data/database.sqlite   # UID/GID used by the n8n container

# 3. Point n8n to the absolute path
echo "N8N_DB_SQLITE_DATABASE_FILE=/home/n8n/data/database.sqlite" >> .env
docker compose up -d

1. Why n8n Can’t Open Its SQLite Database

n8n stores all runtime data in a single SQLite file (default: ~/.n8n/database.sqlite). The runtime calls sqlite3_open_v2; any of the conditions below makes the call return SQLITE_CANTOPEN.

Root cause How it manifests in n8n
File does not exist ENOENT – “No such file or directory”.
Directory missing SQLite cannot create the file because the parent folder isn’t present.
Insufficient permissions EACCES – “Permission denied”.
Wrong path (relative vs absolute) n8n looks in the wrong folder, often /root/ inside a container.
Docker volume mis‑mount Host path not bound, or bind‑mount is read‑only.
SELinux/AppArmor blocking Access denied despite correct POSIX permissions.
File locked by another process Rare; surfaced as SQLITE_BUSY but sometimes as CANTOPEN.

EEFA note: The official Docker image runs as UID 1000. Mismatched ownership is a frequent cause of this error. Learn how to handle SQLite connection and lock issues in n8n along with transaction troubleshooting tips.

2. Step‑by‑Step Verification Checklist

Run the following commands inside the container (docker exec -it n8n sh) to see the view n8n actually has.

 Check Command / Action Expected result
Database file exists ls -l $HOME/.n8n/database.sqlite File listed (or create it).
Parent directory exists dirname $HOME/.n8n/database.sqlitels -ld Directory exists and is writable.
UID/GID match n8n process stat -c '%u %g' $HOME/.n8n/database.sqlite 1000 1000 (or the UID/GID you run as).
Permissions allow read/write ls -l $HOME/.n8n/database.sqlite -rw‑rw‑--- (660) or more permissive.
Env var points to absolute path echo $N8N_DB_SQLITE_DATABASE_FILE Full path, e.g., /home/n8n/data/database.sqlite.
Docker volume is mounted docker inspect <container> --format '{{ json .Mounts }}' Host source path listed, RW.
SELinux/AppArmor not blocking getenforce (SELinux) / aa-status (AppArmor) Permissive/Disabled or policy allowing /data/**.

3. Fix #1 – Ensure the SQLite File Exists

3.1 Create an empty database (if you’re starting fresh)

mkdir -p /home/n8n/data
touch /home/n8n/data/database.sqlite

3.2 Initialise the schema (optional – n8n will auto‑create)

docker run --rm -v /home/n8n/data:/data n8nio/n8n \
  node -e "require('n8n-core').Database.init('/data/database.sqlite')"

EEFA: Never copy a database from a different n8n version without running migrations (n8n migrate).

4. Fix #2 – Correct File Permissions & Ownership

4.1 Set POSIX permissions (read/write for owner & group)

chmod 660 /home/n8n/data/database.sqlite

4.2 Set ownership to the Docker UID/GID (default 1000)

chown 1000:1000 /home/n8n/data/database.sqlite

4.3 Windows hosts – additional notes

On Windows, ensure the file is not marked *Read‑only* and that the Docker Desktop shared drive grants **Full Control** to the user running Docker. Understand how connection timeouts and database locks affect your SQLite workflows in n8n.

5. Fix #3 – Use an Absolute Path (or correct env var)

n8n reads the SQLite location from N8N_DB_SQLITE_DATABASE_FILE. Relative paths resolve inside the container, often to /root/.

# .env in your project root
N8N_DB_SQLITE_DATABASE_FILE=/home/n8n/data/database.sqlite

If you prefer the default location, simply unset the variable; n8n falls back to ~/.n8n/database.sqlite.

EEFA: When running multiple n8n instances on the same host, always use unique absolute paths to avoid cross‑instance collisions.

6. Fix #4 – Docker‑Compose Volume Mapping

6.1 Service definition (core)

services:
  n8n:
    image: n8nio/n8n
    restart: unless-stopped

6.2 Environment configuration

environment:
  - N8N_DB_SQLITE_DATABASE_FILE=/data/database.sqlite

6.3 Volume mount (host ↔ container)

volumes:
  - ./n8n-data:/data:rw   # host folder must exist and be writable
user: "1000:1000"          # optional – forces UID/GID

6.4 Verify the mount from inside the container

docker exec -it n8n sh -c "ls -l /data/database.sqlite"

You should see the same UID/GID you set on the host. Check strategies to recover from transaction failures and other connection-related SQLite issues in n8n.

7. Advanced Troubleshooting

Symptom Diagnostic command Interpretation
Still SQLITE_CANTOPEN after steps docker logs n8n (full stack trace) Stack trace may reveal a *different* path (e.g., /tmp/…).
Error only on start, works after restart Check docker-compose.yml for depends_on – volume may be mounted after n8n starts. Add depends_on: - db or restart: on-failure.
Error persists on **WSL** wslpath -w /home/… – ensure path translation isn’t breaking. Adjust mount syntax for Windows‑style paths.
SELinux “Permission denied” audit2allow -w -a → generate a policy module, then audit2allow -M n8n && semodule -i n8n.pp. Apply the generated module to allow the needed access.

8. Production‑Grade EEFA Checklist

  • Backup strategy – schedule daily backups:
    sqlite3 /data/database.sqlite ".backup /backups/db-$(date +%F).sqlite"
    
  • Read‑only fallback – during maintenance set N8N_DB_SQLITE_READONLY=true to avoid corruption.
  • Filesystem type – avoid network filesystems (NFS, CIFS) that lack proper file‑locking semantics.
  • Health‑check – add a Docker health‑check that runs sqlite3 $DB "SELECT 1"; alert on non‑zero exit.
  • Security – if SELinux/AppArmor is Enforcing, create a minimal profile that only allows read/write on /data/**.

9. Quick Recap

  1. Confirm the DB file exists (touch if needed).
  2. Set permissions to 660 and ownership to the n8n UID/GID.
  3. Use an absolute path via N8N_DB_SQLITE_DATABASE_FILE.
  4. Map the host folder correctly in Docker‑Compose (:rw).
  5. Check SELinux/AppArmor if the error persists.

 

Next Steps

If you’ve resolved the “cannot open database” error but still see sporadic failures, explore the “database is locked” child page for concurrency handling, or set up database backups as described in the production checklist above.

All commands assume a Linux/macOS host; adjust paths and user IDs for Windows or custom Docker users.

Leave a Comment

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