n8n Credentials Could Not Be Decrypted: How to Fix It

The short version: n8n locks your saved passwords and API keys with one encryption key. If that key changes or goes missing, n8n can still see the saved data but can no longer read it. Good news: if you can find the old key, everything comes back in about two minutes. Bad news: if the key is truly gone, those credentials cannot be recovered by anyone. Either way, your workflows are safe โ€” only credentials are encrypted.

You restarted a container, moved to a new server, or ran a routine update. Now n8n loads fine, your workflows are all there โ€” but every credential is broken and the logs say something like “Credentials could not be decrypted. The likely reason is that a different ‘encryptionKey’ was used to encrypt the data.”

This is one of the most common self-hosting mistakes, and almost nobody explains it properly โ€” most answers online stop at “just recreate your credentials.” Often you don’t have to. Let’s go through what actually happened, what to check first, and how to make sure it never happens again.

What this error actually means

When you type a password or API key into n8n, it doesn’t store it as-is. It scrambles it first, using a single secret value called the encryption key. To read that credential back later, n8n needs the exact same key.

Diagram showing how n8n stores credentials: a readable Slack API token on the left, an encryption key in the middle labelled N8N_ENCRYPTION_KEY or the file ~/.n8n/config, and a scrambled unreadable database row on the right. A red panel warns that losing the key makes the database unreadable.
Same key in, same secret out. A different key means the saved data stays locked.

Think of it like the only copy of a house key. n8n put your passwords in a box and locked it. Without that exact key, the box does not open โ€” not for you, not for n8n, not for anyone. There is no master password and no reset link, and that is on purpose: it’s the reason someone who steals your database still can’t read your API keys.

So where does the key come from? The n8n documentation is clear about the default behaviour: n8n “creates a random encryption key automatically on the first launch and saves it in the ~/.n8n folder.” You can also set your own with an environment variable called N8N_ENCRYPTION_KEY.

And that default is the trap. If you never set a key yourself, n8n quietly invented one and saved it inside a folder you may not have realised was precious. Delete that folder, recreate that Docker volume, or move the database to a new server without it โ€” and n8n boots up, generates a brand new key, and can no longer read anything it saved before.

Before you touch anything

Do not delete your credentials yet, and do not run docker compose down -v. That -v flag deletes your volumes, which is exactly where a recoverable key might still be sitting. Every fix below depends on not destroying evidence in the first five minutes of panic.

Take a backup of what you have right now, broken or not. If a later step goes wrong, you can return to this exact point:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  terminal

bash

# copy the n8n data volume somewhere safe first
docker run --rm -v n8n_n8n_data:/data -v $(pwd):/backup \
alpine tar czf /backup/n8n-rescue.tar.gz -C /data .

If your volume has a different name, run docker volume ls to find it.

Which situation are you in?

There are only three. Work through them in order and stop at the first one that matches.

Three-column decision guide for the n8n decryption error. Case 01: the old key still exists in an old .env file, note or running container, so put it back. Case 02: you have a backup of the n8n data volume, so restore it and the key returns. Case 03: the key is truly gone, so re-enter your credentials. A footnote explains workflows and history are not encrypted, only credentials.
Check for the old key before you accept that it’s gone. Most people find it.

Step 1: Find out which key n8n is using now

The key lives in one of two places, and you need to know which one your setup uses. Check the environment variable first:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  terminal

bash

# is a key passed in as an environment variable?
docker compose exec n8n printenv N8N_ENCRYPTION_KEY
# what does n8n have saved in its own config file?
docker compose exec n8n cat /home/node/.n8n/config

What you should see: the first command prints a key, or nothing at all if you never set one. The second prints a small block of JSON containing an encryptionKey value โ€” that’s the one n8n generated for itself.

Write down whatever you find. This is the key that is being used now โ€” the one that doesn’t work. What you’re looking for next is the old one.

Case 1: The old key still exists somewhere

This is the happy ending, and it’s more common than people expect. Go and look in all of these places:

  • An old .env file or docker-compose.yml on your laptop, in a git repository, or in your server-provider’s snapshot
  • The old server, if you migrated and haven’t deleted it yet โ€” the file is at ~/.n8n/config for the user n8n runs as
  • A password manager, a note, or the terminal scrollback from when you first set things up
  • An older container that is stopped but not removed โ€” check docker ps -a, then copy the file out with docker cp

Found it? Put it back as an environment variable, which is the clearest place for it to live. In your docker-compose.yml, under the n8n service’s environment: section, add the old key:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  docker-compose.yml

yaml

  n8n:
    image: n8nio/n8n:latest
    environment:
      - N8N_ENCRYPTION_KEY=paste-your-old-key-here
      # ...your other settings stay as they are

Then rebuild the container so it picks up the change. A plain restart is not always enough โ€” environment variables are read when a container is created, so force a fresh one:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  terminal

bash

docker compose up -d --force-recreate n8n
docker compose logs -f n8n

Open a credential in the n8n editor. If it opens without complaining, you’re done โ€” skip to the prevention section so this never repeats.

Case 2: You have a backup of the n8n data volume

If you never set the key yourself but you do have a backup of the n8n data volume from before things broke, the key is inside that backup โ€” it’s the config file. Restoring the volume brings the key back with it.

Stop n8n, restore the volume contents, then start it again:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  terminal

bash

docker compose stop n8n
# empty the volume, then unpack your backup into it
docker run --rm -v n8n_n8n_data:/data alpine \
sh -c "rm -rf /data/* /data/..?*"
docker run --rm -v n8n_n8n_data:/data -v $(pwd):/backup \
alpine tar xzf /backup/n8n-data.tar.gz -C /data
docker compose start n8n

Don’t want to overwrite the live volume? You only actually need one file. Extract just the config file from your backup, read the encryptionKey value out of it, and then follow Case 1 above โ€” that’s often the safer route.

Case 3: The key is genuinely gone

Then the honest answer is the one nobody wants: those credentials are not coming back. This isn’t a limitation you can work around with a clever command โ€” an n8n maintainer put it plainly on the community forum: there is no way of getting the data back without the original key. Encryption that could be undone without the key wouldn’t be encryption.

Here’s the part that makes it much less painful than it first sounds. Only credentials are encrypted. Your workflows, their logic and connections, your settings and your execution history are all stored normally and are completely unaffected. You are re-entering passwords, not rebuilding your automations.

So, in order:

  1. Set a permanent key first (the next section), so this round of re-entry is the last one.
  2. In the n8n editor, open Credentials and delete the broken entries.
  3. Recreate each one and reconnect it. For most major services this is an OAuth click-through and takes a minute or two each.
  4. Open each affected workflow and confirm the node is pointing at the new credential, then run one test execution before you re-activate it.

Make sure it never happens again

The whole problem comes from letting n8n invent a key and store it somewhere disposable. So take that decision away from it. Generate a strong key yourself:

๐Ÿ”ด ๐ŸŸก ๐ŸŸข  terminal

bash

openssl rand -hex 32

Then build these four habits:

  • Always set N8N_ENCRYPTION_KEY explicitly, from the very first launch of a new instance. Set it before you create a single credential.
  • Store the key in your password manager, not only in the .env file on the server. If the server dies, the key must outlive it.
  • Treat the key as separate from backups. A database backup without the key restores workflows but not credentials โ€” which is exactly how people discover this problem during a real recovery.
  • Never commit it to git. Keep it in .env, and keep .env in .gitignore.

If you’re setting up a new instance from scratch, the encryption key is baked into the Compose file in my complete n8n Docker setup guide, along with backups and HTTPS.

Troubleshooting: it’s still not working

I set the right key but the error hasn’t gone away

Nine times out of ten the container was restarted rather than recreated, so it’s still running with the old environment. Run docker compose up -d --force-recreate n8n, then confirm the new value actually landed with docker compose exec n8n printenv N8N_ENCRYPTION_KEY. Also check for stray whitespace or quotes around the key โ€” KEY="abc" and KEY=abc are not the same value.

Some credentials work and others don’t

That means you have credentials saved under two different keys โ€” usually because the key changed partway through, and anything created after the change was locked with the new one. Whichever key you keep, the other group has to be re-entered. Pick the key that covers the credentials you care about most, then recreate the rest.

It broke after I added extra workers

If you run n8n in queue mode, every worker needs the same encryption key as the main instance. A worker started without it will generate or use a different key and fail to read credentials. Set the same N8N_ENCRYPTION_KEY on every container in the stack.

There’s no config file in the container

That’s normal when the key is supplied through the environment variable โ€” n8n has no need to write one. It also happens when the data volume isn’t mounted where n8n expects. Confirm your volume line maps to /home/node/.n8n, because if it doesn’t, n8n is writing its key into the container’s temporary filesystem and losing it on every rebuild.

What to do next

Once you’re back up, spend ten minutes on the thing that would have prevented all of this: a backup that includes both the database and the data volume, and a restore you’ve actually tested. A backup you’ve never restored is a guess, not a safety net.

More on running your own stack properly is in the Self-Hosting section, and once your instance is stable again, the AI Workflows section covers what to build on top of it.

Hit a variation of this error that isn’t covered here? Send me the exact message and what you’d changed just before it appeared โ€” I’ll add it to this guide and credit you.

One tested workflow, weekly.

Get builds like this one in your inbox. No hype, no spam.

Leave a comment