n8n credentials stopped working after a restart

Every saved credential fails at once, and re-entering them only lasts until the next restart. Here is what happened to them and what can still be recovered.

What you are seeing

The workflows are all still there. The credentials look present in the list. But every node that uses one fails, often with a message about a credential that could not be decrypted, and the services themselves report nothing wrong.

Re-entering a credential by hand fixes that one node until the next restart, and then it breaks again.

Why it happens

The database survived. The key did not.

n8n does not store your passwords and tokens in readable form. It encrypts them with a single encryption key, and that key is what turns the stored value back into a usable password.

If you never set that key yourself, n8n generates a random one the first time it starts and writes it into its own config file at ~/.n8n/config. That file is on disk, and if that disk does not survive a restart, the key is gone. Everything else is fine. The workflows are fine, the credential rows are fine, and none of them can be read any more.

This is why the failure looks so strange. Nothing is missing, so it does not look like data loss, and yet every credential is unusable at exactly the same moment.

The three setups this happens to

A run with no persistent storage at all, where ~/.n8n lives inside the running instance and is recreated from scratch every time it starts.

A move to a new machine or a new host, where the database came along and the config file did not.

A setup where the database is external and healthy, so it survives everything, while ~/.n8n is the part that gets wiped. This is the most confusing version, because the database being safe is exactly what makes people rule out data loss.

How to fix it

First, look for the old key before you do anything else

If you can find the old key, everything comes back with no re-entering at all. Check the old storage if it still exists, and check any backup you have of the machine:

# If the old volume is still around, read the key out of it
docker volume ls
docker run --rm -v n8n_data:/home/node/.n8n alpine cat /home/node/.n8n/config

# Or, if n8n is still running with the old storage attached
docker exec -it n8n cat /home/node/.n8n/config

Put the key back and pin it forever

Set it as an environment variable rather than relying on the config file. An explicitly set key wins, it does not depend on a file surviving, and it is the difference between this being a one-off and a recurring disaster.

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:1.70.0
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    volumes:
      - n8n_data:/home/node/.n8n
volumes:
  n8n_data:

If the key is genuinely gone

Then the stored values cannot be recovered. Not by us, not by n8n, not by anyone. That is what encryption means and it is working as intended.

The recovery is manual and it is dull. Generate a new key, set it explicitly, restart, then open each credential and re-enter it. Delete the ones you no longer use while you are in there. Then rotate anything sensitive on the far side, because a token that has been sitting in an unreadable row for a month is a token worth replacing anyway.

# Generate a key once, then keep it somewhere you will still have in a year
openssl rand -hex 32

Stopping it happening again

Three habits, and this never happens again

Set N8N_ENCRYPTION_KEY explicitly on day one, before you save a single credential. A key you chose is a key you can put back.

Store it where you store passwords, not in the repository next to the compose file. It decrypts every credential you own.

Back it up with the database, not separately. A database backup without the key restores a list of things you cannot read, which is the same failure with extra steps.

The other ways this goes wrong

The setup that avoids most of them, written out in full