N8N_ENCRYPTION_KEY в n8n: почему ломаются credentials и как безопасно переносить инстанс
Обновлено: 2026-05-29
N8N_ENCRYPTION_KEY — один из самых важных секретов self-hosted n8n. Он нужен для защиты credentials: API-токенов, OAuth refresh tokens, паролей SMTP, ключей CRM и других чувствительных данных. Если ключ потерян или отличается между main и worker, workflows могут открываться, но credentials перестанут работать.
Эта проблема часто появляется после “простого” переезда: перенесли PostgreSQL, подняли новый контейнер, забыли старую папку .n8n или не задали ключ в .env. В итоге база есть, workflows есть, а n8n не может расшифровать сохранённые credentials.
Как понять, что проблема именно в encryption key
| Симптом | Что это означает |
|---|---|
| credentials открываются с ошибкой расшифровки | ключ не совпадает с тем, которым они были зашифрованы |
| после переезда все API-запросы стали 401/403 | n8n не смог прочитать токены или credentials повреждены |
| main работает, worker падает на credentials | у worker другой N8N_ENCRYPTION_KEY или переменная не передана |
| OAuth credential требует пересоздания | refresh token недоступен или callback/домен тоже изменились |
Где хранится ключ
Если вы не задали ключ явно, n8n создаёт его при первом запуске и хранит в своей конфигурационной папке. В Docker это обычно volume, смонтированный в /home/node/.n8n. Поэтому перенос только PostgreSQL без volume может привести к потере ключа.
services:
n8n:
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
Для production лучше задавать ключ явно через .env или секретное хранилище. Тогда поведение не зависит от случайно созданного файла в volume.
Как сгенерировать ключ для нового инстанса
Ключ должен быть длинным и случайным. Пример:
openssl rand -base64 32
Сохраните значение в закрытом password manager или vault. Не отправляйте его в чат, не коммитьте в публичный репозиторий и не храните рядом с открытым docker-compose.yml.
Правильный перенос n8n на новый сервер
- На старом сервере найдите текущее значение
N8N_ENCRYPTION_KEYили сохраните volume/home/node/.n8n. - Сделайте backup PostgreSQL.
- Скопируйте compose,
.env, Caddy/Nginx/Traefik конфиги и backup. - На новом сервере задайте тот же
N8N_ENCRYPTION_KEY. - Восстановите PostgreSQL.
- Запустите n8n и проверьте credentials test на 3–5 ключевых интеграциях.
- Обновите
WEBHOOK_URLи OAuth redirect URL, если изменился домен.
Queue mode: ключ должен быть везде одинаковым
В queue mode credentials читают не только main-процесс, но и workers. Поэтому одинаковый N8N_ENCRYPTION_KEY должен быть у всех контейнеров n8n:
services:
n8n:
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
n8n-worker:
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- EXECUTIONS_MODE=queue
Если main и worker используют разные ключи, часть workflow может выглядеть рабочей в UI, но падать при реальном запуске на worker.
Что делать, если ключ уже потерян
Сначала не пересоздавайте credentials массово. Проверьте:
- остался ли старый Docker volume на сервере;
- есть ли backup
.envили snapshot VPS; - не лежит ли ключ в Portainer Stack, CI/CD variables, secrets manager;
- есть ли старая копия
configв/home/node/.n8n.
Если ключ действительно потерян, расшифровать старые credentials штатным способом не получится. Практический путь — восстановить workflows, пересоздать credentials, перепроверить OAuth и запустить smoke-tests. Поэтому ключ должен входить в список обязательных backup-артефактов.
Поворот ключей и обычная замена — разные вещи
Не путайте потерю instance key с управляемой ротацией. Управляемая ротация — это отдельная функция, где instance key остаётся базовым секретом, а данные перевыпускаются контролируемо. Просто заменить N8N_ENCRYPTION_KEY в .env — не ротация, а почти гарантированный способ сломать credentials.
Checklist перед переездом
N8N_ENCRYPTION_KEYнайден и сохранён в закрытом месте;- PostgreSQL dump создан и восстановление протестировано на отдельной базе;
- volume
/home/node/.n8nсохранён, если ключ не задан явно; - для queue mode ключ передан main, worker и webhook processor;
- после запуска проверены credentials для CRM, Telegram, SMTP, Google, платежей;
- домены и OAuth callback URL совпадают с новым адресом.
Ручная диагностика перед исправлением ¶
Перед тем как менять настройки по теме «N8N_ENCRYPTION_KEY в n8n», зафиксируйте не только текст ошибки, но и последний успешный запуск. Для n8n это критично: один и тот же симптом может появиться из-за credentials, изменения payload, лимита API, обновления версии или инфраструктурного сбоя.
Рабочий порядок: изолируйте один execution, сохраните входной item без секретов, проверьте branch с ошибкой и только потом меняйте workflow. Главный риск — исправить симптом на одной ноде, но оставить первопричину в credentials, payload, лимитах API или окружении.
| Слой | Что зафиксировать | Зачем |
|---|---|---|
| Вход | входной item по теме «N8N_ENCRYPTION_KEY в n8n»: источник события, внешний ID, время получения и нормализованные поля | позволяет повторить проблему без доступа к production-секретам |
| Контроль | error_count_by_node, retry_count, first_failed_execution, last_successful_execution, affected_workflows | показывает деградацию раньше, чем пользователи начинают писать в поддержку |
| Безопасность | исправить симптом на одной ноде, но оставить первопричину в credentials, payload, лимитах API или окружении | снижает риск скрытых дублей, утечки данных и неконтролируемых write-действий |
| Готовность | есть тест на happy path, пустой вход, повтор и сбой внешнего сервиса для «N8N_ENCRYPTION_KEY в n8n» | делает статью пригодной для runbook, а не только для чтения |
Пример безопасного входного контракта ¶
{
"execution_id": "exec_...",
"workflow_id": "wf_...",
"node_name": "node_with_symptom",
"error_message": "точный текст ошибки без токенов",
"input_item_id": "external_or_dedupe_id",
"last_successful_run": "timestamp",
"changed_before_error": ["credentials", "payload", "version", "env"]
}
Критерий готовности ¶
- точный текст ошибки сохранён без токенов и персональных данных
- понятно, какая нода упала первой, а какие ошибки были следствием
- есть минимальный воспроизводимый workflow или тестовый execution
- после исправления проверены retry, error branch и последний успешный сценарий