
Step by Step Guide to Enable and Use SQLite Logging in n8n for Debugging
Who this is for: n8n administrators and workflow developers who need to diagnose SQLite‑related failures in production or staging environments. For a complete guide on managing SQLite in n8n, including errors, performance, and migration, check out our n8n SQLite pillar guide.
Quick Diagnosis
| Step | Action | Command / Setting | Expected Result |
|---|---|---|---|
| 1 | Set log level to debug for SQLite | N8N_LOG_LEVEL=debug (env) |
n8n prints all SQLite statements to stdout |
| 2 | Enable file‑based SQLite logs | N8N_SQLITE_LOG_PATH=/var/log/n8n/sqlite.log (env) |
Log file created, rotated automatically |
| 3 | Restart the n8n service | docker restart n8n or systemctl restart n8n |
New settings take effect |
| 4 | Reproduce the error in your workflow | Run the failing node | Corresponding SQL statements appear in the log |
| 5 | Search the log for the error code | grep -i "SQLITE_.*" /var/log/n8n/sqlite.log |
Identify the exact SQLite error (e.g., SQLITE_BUSY) |
| 6 | Apply the corrective action (e.g., increase timeout, fix schema) | Follow the “Common SQLite Errors” table below | Workflow runs without error |
Featured snippet ready: To enable SQLite logging in n8n, set
N8N_LOG_LEVEL=debugandN8N_SQLITE_LOG_PATHenvironment variables, then restart n8n. The log file will contain every SQL statement and SQLite error code, which you can grep to pinpoint issues. Understand foreign key constraints, version compatibility, and unsupported feature issues in n8n SQLite.
1. Why SQLite Logging Matters in n8n
n8n stores workflow state, execution metadata, and credential data in a local SQLite database by default. When a node fails with a cryptic “SQLITE_….” error, the only reliable way to understand the root cause is to inspect the raw SQL that n8n sent to SQLite.
- Visibility into each
SELECT,INSERT,UPDATE, andPRAGMAcall. - Error codes (
SQLITE_BUSY,SQLITE_CONSTRAINT, …) tied to the exact statement. - Performance clues – long‑running queries appear with timestamps.
EEFA note: Never leave
N8N_LOG_LEVEL=debugpermanently on in production; it can expose credentials and flood storage. Use file‑based logging with rotation and restrict file permissions (chmod 600).
2. Enabling SQLite Logging
2.1. Docker (environment variables)
Set the required variables and run the container.
# Export variables for clarity (optional) export N8N_LOG_LEVEL=debug export N8N_SQLITE_LOG_PATH=/var/log/n8n/sqlite.log export N8N_SQLITE_LOG_MAX_SIZE=10485760 # 10 MiB export N8N_SQLITE_LOG_MAX_FILES=5
docker run -d \ -e N8N_LOG_LEVEL=$N8N_LOG_LEVEL \ -e N8N_SQLITE_LOG_PATH=$N8N_SQLITE_LOG_PATH \ -e N8N_SQLITE_LOG_MAX_SIZE=$N8N_SQLITE_LOG_MAX_SIZE \ -e N8N_SQLITE_LOG_MAX_FILES=$N8N_SQLITE_LOG_MAX_FILES \ -v /var/log/n8n:/var/log/n8n \ n8nio/n8n:latest
2.2. Systemd service (Ubuntu)
Create the service unit with the logging variables.
# /etc/systemd/system/n8n.service [Unit] Description=n8n workflow automation After=network.target [Service] Environment="N8N_LOG_LEVEL=debug" Environment="N8N_SQLITE_LOG_PATH=/var/log/n8n/sqlite.log" Environment="N8N_SQLITE_LOG_MAX_SIZE=10485760" Environment="N8N_SQLITE_LOG_MAX_FILES=5" ExecStart=/usr/local/bin/n8n Restart=on-failure User=n8n Group=n8n [Install] WantedBy=multi-user.target
# Reload systemd, enable and start n8n systemctl daemon-reload systemctl enable --now n8n
EEFA warning: Ensure
/var/log/n8nexists and is owned by then8nuser; otherwise SQLite logs will be silently dropped.
2.3. .env file (non‑Docker)
Create a .env file alongside the n8n binary.
# .env N8N_LOG_LEVEL=debug N8N_SQLITE_LOG_PATH=./logs/sqlite.log N8N_SQLITE_LOG_MAX_SIZE=10485760 N8N_SQLITE_LOG_MAX_FILES=5
Start n8n with dotenv support:
npm install -g dotenv-cli # if not already installed dotenv -e .env n8n
3. Interpreting the Log Entries
n8n writes SQLite logs as JSON‑lines, making them easy to pipe into jq.
3.1. Typical log line (compact view)
{"timestamp":"2025-12-24T14:32:07.123Z","level":"debug","source":"sqlite","msg":"Executed query","sql":"INSERT INTO \"execution_entity\" (\"id\",\"workflowId\",\"startedAt\") VALUES (?,?,?)","params":["c1a2b3d4","5f6e7d8c","2025-12-24T14:32:07.123Z"],"durationMs":3}
- timestamp – When the query ran.
- sql – Raw statement.
- params – Parameter array (useful for data‑type mismatches).
- durationMs – Execution time; > 100 ms may indicate lock contention.
3.2. Filtering for errors
grep -i '"msg":"Error"' /var/log/n8n/sqlite.log | jq .
Sample error entry (compact):
{"timestamp":"2025-12-24T14:45:22.987Z","level":"debug","source":"sqlite","msg":"Error","sql":"UPDATE \"execution_entity\" SET \"status\"=? WHERE \"id\"=?","params":["failed","c1a2b3d4"],"errorCode":"SQLITE_BUSY","errorMessage":"database is locked"}
4. Common SQLite Error Codes in n8n & Fixes
| SQLite Error | Typical n8n Trigger | Root Cause | Quick Fix |
|---|---|---|---|
| SQLITE_BUSY | Workflow execution stalls | Database locked by another process | Increase N8N_SQLITE_BUSY_TIMEOUT (default 5000 ms) or split heavy reads into separate transactions |
| SQLITE_CONSTRAINT | Credential save fails | Unique‑constraint violation (duplicate name) | Ensure credential names are unique; use ON CONFLICT REPLACE only if intentional |
| SQLITE_FULL | New execution cannot be inserted | Disk quota exhausted or DB size limit reached | Expand storage, prune old executions (n8n execution delete) |
| SQLITE_READONLY | Write attempt in read‑only mode | File‑system permissions changed after start | Verify chmod 660 on database.sqlite and that the n8n user owns it |
| SQLITE_CORRUPT | Random crashes | Corrupted DB file (power loss, abrupt stop) | Restore from backup; run sqlite3 database.sqlite "PRAGMA integrity_check;" |
EEFA tip: From n8n v0.210 onward, you can set a per‑workflow timeout via Workflow Settings → Advanced → SQLite Busy Timeout, which overrides the global env var.
5. Step‑by‑Step Debugging Workflow
- Activate logging (see Section 2).
- Reproduce the failure – run the problematic node or trigger the webhook.
- Locate the offending query:
grep -i '"msg":"Error"' /var/log/n8n/sqlite.log | tail -n 20
- Identify the error code (
SQLITE_…). - Cross‑reference with the table in Section 4 to understand the cause.
- Apply the corrective action (e.g., increase timeout, fix schema).
- Validate by re‑running the workflow and confirming the log no longer shows the error.
- Learn to Handle unsupported SQLite features, constraints, and version issues in n8n workflows.
5.1. Example: Fixing a SQLITE_BUSY During Bulk Inserts
# Observe repeated SQLITE_BUSY lines grep SQLITE_BUSY /var/log/n8n/sqlite.log
**Log excerpt (compact)**
{"timestamp":"2025-12-24T15:01:12.045Z","level":"debug","source":"sqlite","msg":"Error","sql":"INSERT INTO \"execution_entity\" ...","errorCode":"SQLITE_BUSY","errorMessage":"database is locked"}
**Fix – increase busy timeout**
export N8N_SQLITE_BUSY_TIMEOUT=15000 # 15 seconds systemctl restart n8n # or docker restart n8n
Re‑run the workflow; the log now shows successful inserts with durationMs < 5 ms.
6. Log Rotation & Retention (Production‑Grade)
Configure built‑in rotation via environment variables (already shown) and complement it with a system‑wide logrotate policy.
# /etc/logrotate.d/n8n-sqlite
/var/log/n8n/sqlite.log* {
daily
rotate 14
compress
missingok
notifempty
create 0600 n8n n8n
sharedscripts
postrotate
systemctl reload n8n > /dev/null 2>/dev/null || true
endscript
}
# Test the configuration logrotate -d /etc/logrotate.d/n8n-sqlite
EEFA caution: Do not compress logs while n8n is actively writing to them; the
postrotatehook safely reloads the service after rotation.
7. Real‑Time Monitoring with tail & jq
For instant feedback while iterating on a workflow:
tail -f /var/log/n8n/sqlite.log | \
jq 'select(.msg=="Error") | {time:.timestamp, sql:.sql, code:.errorCode, msg:.errorMessage}'
This streams only error entries, showing timestamp, offending SQL, and the SQLite error code—ideal for a live debugging console.
8. Security Considerations
- Mask sensitive data – set
N8N_LOG_SENSITIVE_DATA=falseto prevent credential values from appearing inparams. - Restrict log file access
chown n8n:n8n /var/log/n8n/sqlite.log* chmod 600 /var/log/n8n/sqlite.log*
- Docker best practice – mount the log directory as a read‑only volume on the host side and let the container manage rotation internally.
10. Next Steps
- Implement logging on a staging environment first; verify that no credential values leak.
- Run a health‑check script that parses the last 24 h of logs for any
SQLITE_errors and alerts you via Slack. - Explore sibling pages for targeted fixes (e.g., “n8n SQLite schema mismatch” or “n8n SQLite file‑permission errors”).
Conclusion
Enabling SQLite logging gives you a transparent view into the exact queries n8n executes, turning opaque “SQLITE_…” errors into actionable insights. Ensure smooth operation by addressing version conflicts, unsupported features, and constraint errors in n8n SQLite. By configuring environment‑driven logging, rotating logs responsibly, and filtering for errors with lightweight jq pipelines, you can quickly pinpoint lock contention, constraint violations, and other database issues without guessing. Apply the focused fixes from the error‑code table, and keep logging at debug level only when needed to maintain security and performance in production.



