<p style="text-align: center;"><img class="alignfull wp-image-3550" src="https://flowgenius.in/wp-content/uploads/2025/12/12.png" alt="" /></p>
<p style="text-align: center;">Step by Step Guide for Logging Redis Errors in n8n</p>
<p> </p>
<p> </p>
<p> </p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for:</strong> Developers and SREs running n8n in production who need full visibility into Redis‑related failures for debugging, compliance, and observability. For a complete overview of Redis usage, errors, performance tuning, and scaling in n8n, check out our detailed guide on <a href="https://flowgenius.in/n8n-redis-error-troubleshooting-guide/"><strong><em data-start="361" data-end="386">Redis for n8n Workflows</em></strong></a>.</p>
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick Diagnosis</h2>
<ol style="margin-bottom: 1.7em; line-height: 1.9;">
<li>Set <code>N8N_LOG_LEVEL=debug</code> and <code>N8N_REDIS_LOGGING=true</code> in your n8n environment.</li>
<li>Add a <strong>custom logger</strong> in <code>~/.n8n/custom/logger.js</code> that forwards Redis error events to your external log sink (e.g., Loki, Datadog, ELK).</li>
<li>Register the logger in <code>~/.n8n/custom/index.js</code> with <code>n8nCore.addErrorListener('redis', redisErrorHandler)</code>.</li>
<li>Restart n8n – every Redis error now appears in the n8n UI <strong>and</strong> in the external sink with full stack trace, command, and key name.</li>
</ol>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">1. Why a Dedicated Redis‑Error Logger?</h2>
<ul style="margin-bottom: 1.7em; line-height: 1.9;">
<li><strong>Visibility</strong> – n8n’s default logger only shows “Redis error”, obscuring the root cause.</li>
<li><strong>Compliance</strong> – SOC‑2 / ISO‑27001 audits often require full error payloads to be retained.</li>
<li><strong>Correlation</strong> – Centralized observability lets you link Redis errors with workflow failures, CPU spikes, or network latency.</li>
</ul>
<blockquote style="margin: 0 0 2em; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin-bottom: 0; line-height: 1.9;"><strong>EEFA note:</strong> Never log raw Redis keys that contain PII. Mask or hash them before shipping to external services.</p>
</blockquote>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">2. Prerequisites</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Requirement</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Minimum Version</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Verify</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">n8n core</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`0.250.0` (or later)</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`n8n -v`</td>
</tr>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Node.js</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`18.x` LTS</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`node -v`</td>
</tr>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Redis client (ioredis)</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`5.2+` (bundled)</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`npm ls ioredis`</td>
</tr>
<tr>
<td style="padding: 13px;">External log sink (optional)</td>
<td style="padding: 13px;">–</td>
<td style="padding: 13px;">Follow provider docs (Loki, Datadog, ELK)</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Tip:</em> Use the official <a href="https://flowgenius.in/docker-redis-setup-for-n8n/"><strong>n8n‑docker</strong></a> image for a reproducible environment; the steps below work identically on bare‑metal installs.</p>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">3. Enable Redis‑Error Emission in n8n</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">n8n does not expose Redis errors by default. Add two environment variables:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">export N8N_LOG_LEVEL=debug # Preserve full error objects
export N8N_REDIS_LOGGING=true # Emit ‘redis’ events
</pre>
<blockquote style="margin: 0 0 2em; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin-bottom: 0; line-height: 1.9;"><strong>EEFA warning:</strong> <code>debug</code> level logs can be noisy. In high‑traffic clusters, run a side‑car container that only forwards Redis logs to avoid overwhelming the main log stream. Facing <a href="https://flowgenius.in/n8n-redis-connection-refused-error/"><strong>connection issues with Redis in n8n</strong></a>? Explore our full n8n Redis guide for solutions and best practices.</p>
</blockquote>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">4. Create a Custom Logger</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.1 Directory layout</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">~/.n8n/
├─ custom/
│ ├─ logger.js # Redis‑error handler
│ └─ index.js # Registers the handler with n8n core
└─ .env # Contains the two vars above
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.2 <code>logger.js</code> – core logic</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Choose a transport</strong> (Loki example or fallback to console):</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">const { LokiTransport } = require('winston-loki');
const winston = require('winston');
const transport = process.env.LOG_SINK === 'loki'
? new LokiTransport({
host: process.env.LOKI_URL,
basicAuth: process.env.LOKI_AUTH,
labels: { service: 'n8n', component: 'redis' },
})
: new winston.transports.Console();
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Create the Winston logger</strong>:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">const logger = winston.createLogger({
level: 'error',
format: winston.format.json(),
transports: [transport],
});
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Define the Redis error handler</strong> (masking PII in keys):</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">function redisErrorHandler(err, context) {
const payload = {
message: err.message,
name: err.name,
stack: err.stack,
command: context.command,
key: /email/.test(context.key) ? context.key.replace(/[^:]+$/, '***') : context.key,
args: context.args,
clientId: context.clientId,
timestamp: new Date().toISOString(),
};
logger.error(payload);
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Export the handler</strong> for registration:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">module.exports = { redisErrorHandler };
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.3 <code>index.js</code> – hook into n8n core</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">const { redisErrorHandler } = require('./logger');
const { n8nCore } = require('n8n-core'); // internal API
// Register once on startup
n8nCore.addErrorListener('redis', redisErrorHandler);
</pre>
<blockquote style="margin: 0 0 2em; padding-left: 1em; border-left: 4px solid #ddd;">
<p style="margin-bottom: 0; line-height: 1.9;"><strong>EEFA note:</strong> <code>n8nCore.addErrorListener</code> is a private API. Pin your n8n version or test after each upgrade.</p>
</blockquote>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">5. Wire the Custom Code into n8n</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">When using Docker, mount the <code>custom</code> folder and set <code>N8N_CUSTOM_EXTENSIONS</code>:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">services:
n8n:
image: n8nio/n8n:0.250
environment:
- N8N_LOG_LEVEL=debug
- N8N_REDIS_LOGGING=true
- N8N_CUSTOM_EXTENSIONS=/home/node/.n8n/custom
- LOG_SINK=loki
- LOKI_URL=https://logs.example.com
- LOKI_AUTH=base64(user:pass)
</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;"> volumes:
- ./n8n-data:/home/node/.n8n
- ./custom:/home/node/.n8n/custom
ports:
- "5678:5678"
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Deploy with <code>docker compose up -d</code>. n8n loads <code>index.js</code> automatically and forwards any Redis error event to the chosen sink.</p>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">6. Verify the Pipeline</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Step</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Action</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Expected Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">1</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Trigger a known Redis error (e.g., <code>GET</code> on a key of the wrong type) via a test workflow</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">UI shows “Redis error” in the execution log</td>
</tr>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">2</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Query the external sink (Loki UI, Datadog) for <code>service=n8n</code> & <code>component=redis</code></td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">JSON payload with <code>command</code>, <code>key</code>, <code>stack</code> appears</td>
</tr>
<tr>
<td style="padding: 13px;">3</td>
<td style="padding: 13px;">Confirm masking – keys containing “email” appear as <code>user:email:***</code></td>
<td style="padding: 13px;">No raw email addresses in logs</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Quick test workflow (Execute Command node)</strong></p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"nodes": [
{
"parameters": {
"command": "GET",
"key": "user:email:12345"
},
"name": "Redis Get (error)",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [200, 300]
}
],
"connections": {}
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Running this workflow generates a *WRONGTYPE* error that the custom logger captures. Learn how to handle <a href="https://flowgenius.in/how-to-fix-the-n8n-redis-timeout-error/"><strong>Redis timeout issues in n8n</strong></a> effectively in our detailed n8n Redis guide.</p>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">7. Advanced: Correlating with Workflow Failures</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">Include the workflow execution ID in the log payload:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">function redisErrorHandler(err, context) {
const executionId = context?.executionId ?? 'unknown';
const payload = { /* previous fields */ executionId };
logger.error(payload);
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Now you can query:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{service="n8n", component="redis", executionId="12345"}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">to see which workflow triggered the Redis fault.</p>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">8. Common Pitfalls & Troubleshooting</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Symptom</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Likely Cause</th>
<th style="padding: 13px; text-align: left; border-bottom: 1px solid #ddd;">Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">No logs in external sink</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">`N8N_REDIS_LOGGING` not set or env not loaded</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Verify with <code>docker exec <container> printenv | grep N8N_REDIS_LOGGING</code></td>
</tr>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Duplicate log lines flood console</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Transport set to <code>Console</code> **and** <code>debug</code> level prints the same error</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Use <code>new winston.transports.Console({ silent: true })</code> for UI‑only logging</td>
</tr>
<tr>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Masking fails – raw PII still present</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Regex too specific</td>
<td style="padding: 13px; border-bottom: 1px solid #eee;">Adopt a broader pattern or a dedicated <strong>PII‑scrubber</strong> library</td>
</tr>
<tr>
<td style="padding: 13px;">Errors disappear after n8n upgrade</td>
<td style="padding: 13px;">Private API <code>addErrorListener</code> changed</td>
<td style="padding: 13px;">Pin n8n version (<code>0.250.x</code>) or migrate to the new <code>n8nCore.on('redisError', …)</code> event (check release notes)</td>
</tr>
</tbody>
</table>
<div style="margin: 55px 0;"></div>
<h2 style="margin-bottom: 45px; line-height: 1.3;">9. Production‑Ready Checklist</h2>
<ul style="margin-bottom: 1.7em; line-height: 1.9;">
<li>Set <code>N8N_LOG_LEVEL</code> and <code>N8N_REDIS_LOGGING</code> via immutable config (Docker secret, K8s ConfigMap).</li>
<li>Store log‑sink credentials in a secret manager (AWS Secrets Manager, Vault).</li>
<li>Review PII‑masking rules quarterly with the security team.</li>
<li>Create an alert: fire when <code>redis</code> error count > 5 per minute (Grafana/Loki query).</li>
<li>Configure log‑index retention (e.g., 30 days) to satisfy compliance.</li>
</ul>
<p> </p>
<h2 style="margin-bottom: 45px; line-height: 1.3;">Next Steps</h2>
<ol style="margin-bottom: 1.7em; line-height: 1.9;">
<li>Implement alerting on the log sink (e.g., Loki → Alertmanager).</li>
<li>Add structured metrics (Prometheus) for error rates (<code>n8n_redis_error_total</code>).</li>
<li>Explore batch shipping (e.g., <code>winston-bulk</code>) if your volume exceeds 10 k errors/min.</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>All commands assume a Unix‑like shell. Adjust paths for Windows PowerShell as needed.</em></p>

Step by Step Guide for Logging Redis Errors in n8n
Who this is for: Developers and SREs running n8n in production who need full visibility into Redis‑related failures for debugging, compliance, and observability. For a complete overview of Redis usage, errors, performance tuning, and scaling in n8n, check out our detailed guide on Redis for n8n Workflows.
Quick Diagnosis
- Set
N8N_LOG_LEVEL=debug and N8N_REDIS_LOGGING=true in your n8n environment.
- Add a custom logger in
~/.n8n/custom/logger.js that forwards Redis error events to your external log sink (e.g., Loki, Datadog, ELK).
- Register the logger in
~/.n8n/custom/index.js with n8nCore.addErrorListener('redis', redisErrorHandler).
- Restart n8n – every Redis error now appears in the n8n UI and in the external sink with full stack trace, command, and key name.
1. Why a Dedicated Redis‑Error Logger?
- Visibility – n8n’s default logger only shows “Redis error”, obscuring the root cause.
- Compliance – SOC‑2 / ISO‑27001 audits often require full error payloads to be retained.
- Correlation – Centralized observability lets you link Redis errors with workflow failures, CPU spikes, or network latency.
EEFA note: Never log raw Redis keys that contain PII. Mask or hash them before shipping to external services.
2. Prerequisites
| Requirement |
Minimum Version |
Verify |
| n8n core |
`0.250.0` (or later) |
`n8n -v` |
| Node.js |
`18.x` LTS |
`node -v` |
| Redis client (ioredis) |
`5.2+` (bundled) |
`npm ls ioredis` |
| External log sink (optional) |
– |
Follow provider docs (Loki, Datadog, ELK) |
Tip: Use the official n8n‑docker image for a reproducible environment; the steps below work identically on bare‑metal installs.
3. Enable Redis‑Error Emission in n8n
n8n does not expose Redis errors by default. Add two environment variables:
export N8N_LOG_LEVEL=debug # Preserve full error objects
export N8N_REDIS_LOGGING=true # Emit ‘redis’ events
EEFA warning: debug level logs can be noisy. In high‑traffic clusters, run a side‑car container that only forwards Redis logs to avoid overwhelming the main log stream. Facing connection issues with Redis in n8n? Explore our full n8n Redis guide for solutions and best practices.
4. Create a Custom Logger
4.1 Directory layout
~/.n8n/
├─ custom/
│ ├─ logger.js # Redis‑error handler
│ └─ index.js # Registers the handler with n8n core
└─ .env # Contains the two vars above
4.2 logger.js – core logic
Choose a transport (Loki example or fallback to console):
const { LokiTransport } = require('winston-loki');
const winston = require('winston');
const transport = process.env.LOG_SINK === 'loki'
? new LokiTransport({
host: process.env.LOKI_URL,
basicAuth: process.env.LOKI_AUTH,
labels: { service: 'n8n', component: 'redis' },
})
: new winston.transports.Console();
Create the Winston logger:
const logger = winston.createLogger({
level: 'error',
format: winston.format.json(),
transports: [transport],
});
Define the Redis error handler (masking PII in keys):
function redisErrorHandler(err, context) {
const payload = {
message: err.message,
name: err.name,
stack: err.stack,
command: context.command,
key: /email/.test(context.key) ? context.key.replace(/[^:]+$/, '***') : context.key,
args: context.args,
clientId: context.clientId,
timestamp: new Date().toISOString(),
};
logger.error(payload);
}
Export the handler for registration:
module.exports = { redisErrorHandler };
4.3 index.js – hook into n8n core
const { redisErrorHandler } = require('./logger');
const { n8nCore } = require('n8n-core'); // internal API
// Register once on startup
n8nCore.addErrorListener('redis', redisErrorHandler);
EEFA note: n8nCore.addErrorListener is a private API. Pin your n8n version or test after each upgrade.
5. Wire the Custom Code into n8n
When using Docker, mount the custom folder and set N8N_CUSTOM_EXTENSIONS:
services:
n8n:
image: n8nio/n8n:0.250
environment:
- N8N_LOG_LEVEL=debug
- N8N_REDIS_LOGGING=true
- N8N_CUSTOM_EXTENSIONS=/home/node/.n8n/custom
- LOG_SINK=loki
- LOKI_URL=https://logs.example.com
- LOKI_AUTH=base64(user:pass)
volumes:
- ./n8n-data:/home/node/.n8n
- ./custom:/home/node/.n8n/custom
ports:
- "5678:5678"
Deploy with docker compose up -d. n8n loads index.js automatically and forwards any Redis error event to the chosen sink.
6. Verify the Pipeline
| Step |
Action |
Expected Result |
| 1 |
Trigger a known Redis error (e.g., GET on a key of the wrong type) via a test workflow |
UI shows “Redis error” in the execution log |
| 2 |
Query the external sink (Loki UI, Datadog) for service=n8n & component=redis |
JSON payload with command, key, stack appears |
| 3 |
Confirm masking – keys containing “email” appear as user:email:*** |
No raw email addresses in logs |
Quick test workflow (Execute Command node)
{
"nodes": [
{
"parameters": {
"command": "GET",
"key": "user:email:12345"
},
"name": "Redis Get (error)",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [200, 300]
}
],
"connections": {}
}
Running this workflow generates a *WRONGTYPE* error that the custom logger captures. Learn how to handle Redis timeout issues in n8n effectively in our detailed n8n Redis guide.
7. Advanced: Correlating with Workflow Failures
Include the workflow execution ID in the log payload:
function redisErrorHandler(err, context) {
const executionId = context?.executionId ?? 'unknown';
const payload = { /* previous fields */ executionId };
logger.error(payload);
}
Now you can query:
{service="n8n", component="redis", executionId="12345"}
to see which workflow triggered the Redis fault.
8. Common Pitfalls & Troubleshooting
| Symptom |
Likely Cause |
Fix |
| No logs in external sink |
`N8N_REDIS_LOGGING` not set or env not loaded |
Verify with docker exec <container> printenv | grep N8N_REDIS_LOGGING |
| Duplicate log lines flood console |
Transport set to Console **and** debug level prints the same error |
Use new winston.transports.Console({ silent: true }) for UI‑only logging |
| Masking fails – raw PII still present |
Regex too specific |
Adopt a broader pattern or a dedicated PII‑scrubber library |
| Errors disappear after n8n upgrade |
Private API addErrorListener changed |
Pin n8n version (0.250.x) or migrate to the new n8nCore.on('redisError', …) event (check release notes) |
9. Production‑Ready Checklist
- Set
N8N_LOG_LEVEL and N8N_REDIS_LOGGING via immutable config (Docker secret, K8s ConfigMap).
- Store log‑sink credentials in a secret manager (AWS Secrets Manager, Vault).
- Review PII‑masking rules quarterly with the security team.
- Create an alert: fire when
redis error count > 5 per minute (Grafana/Loki query).
- Configure log‑index retention (e.g., 30 days) to satisfy compliance.
Next Steps
- Implement alerting on the log sink (e.g., Loki → Alertmanager).
- Add structured metrics (Prometheus) for error rates (
n8n_redis_error_total).
- Explore batch shipping (e.g.,
winston-bulk) if your volume exceeds 10 k errors/min.
All commands assume a Unix‑like shell. Adjust paths for Windows PowerShell as needed.