Email customisation not being picked up

Describe the problem/error/question

Am trying to use the email customisation feature with our self-hosted n8n

I have set the following environment variables as

N8N_UM_EMAIL_TEMPLATES_CREDENTIALS_SHARED = /templates/credentials-shared.handlebars

N8N_UM_EMAIL_TEMPLATES_INVITE = /templates/user-invited.handlebars

N8N_UM_EMAIL_TEMPLATES_PROJECT_SHARED = /templates/credentials-shared.handlebars

N8N_UM_EMAIL_TEMPLATES_PWRESET = /templates/password-reset-requested.handlebars

N8N_UM_EMAIL_TEMPLATES_WORKFLOW_SHARED = /templates/workflow-shared.handlebars

I also tried

N8N_UM_EMAIL_TEMPLATES_CREDENTIALS_SHARED = /templates/credentials-shared.handlebars

N8N_UM_EMAIL_TEMPLATES_INVITE = ./templates/user-invited.handlebars

N8N_UM_EMAIL_TEMPLATES_PROJECT_SHARED = ./templates/credentials-shared.handlebars

N8N_UM_EMAIL_TEMPLATES_PWRESET = ./templates/password-reset-requested.handlebars

N8N_UM_EMAIL_TEMPLATES_WORKFLOW_SHARED = ./templates/workflow-shared.handlebars

but its still sending out the default n8n branded

What is the error message (if any)?

I don’t know where to look, the log in cloudwatch just says 2026-01-29T12:24:21.020Z
Sent password reset email successfully

Information on your n8n setup

  • n8n version: 2.3.5
  • Database (default: SQLite): Postgres
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): AWS Fargate (docker)
  • Operating system: AWS Fargate (docker)

Hi @Neil_Carmichael

This is expected behavior and usually happens in container setups like Fargate.

Your environment variables are fine, but n8n will only use custom email templates if the .handlebars files actually exist inside the running container. If the files aren’t mounted, n8n silently falls back to the default branded emails and does not log an error.

What to do:

  • Mount a templates folder into the container (for example /opt/n8n/templates)
  • Point the env vars to that absolute path
  • Restart the container

Relative paths don’t work reliably, and templates are only loaded at startup. Once the files are properly mounted, the custom emails will be picked up.

Hi,

I had already mounted an EFS and bound it to the root

hi @Neil_Carmichael

Thanks for sharing the screenshots and the details — that helped clarify the situation.

the reason the custom emails are not being picked up is where and how the templates are mounted inside the container. This is expected behavior in Docker/Fargate setups and is documented by n8n.

n8n does not search for email templates automatically and does not log an error if they are missing.

According to the n8n documentation, custom email templates are:

  • Loaded only once at startup
  • Loaded only from the exact absolute paths defined in the environment variables
  • Silently ignored if the file does not exist or is not readable

In your case:

  • You mounted EFS to / (root)
  • The template paths technically exist on EFS
  • But in Fargate, mounting to / makes file resolution unreliable
  • As a result, when n8n starts, it does not see the template files where it expects them
  • n8n then falls back to the default branded templates (by design)

This is why:

  • Emails are sent successfully
  • No error appears in the logs
  • Branding remains unchanged

This behavior is explicitly described in the n8n email customization documentation.

solution (recommended by n8n)

1. Mount EFS to a dedicated directory

Update your Fargate task definition to mount EFS to a clear, explicit path, for example:

/opt/n8n/templates

Do not mount it to /.


2. Place the templates in that directory

Inside EFS, ensure the files exist exactly as expected:

/opt/n8n/templates/credentials-shared.handlebars
/opt/n8n/templates/user-invited.handlebars
/opt/n8n/templates/password-reset-requested.handlebars
/opt/n8n/templates/workflow-shared.handlebars

You should be able to confirm this inside the running container with:

ls /opt/n8n/templates

3. Use absolute paths in environment variables

Set the environment variables like this:

N8N_UM_EMAIL_TEMPLATES_CREDENTIALS_SHARED=/opt/n8n/templates/credentials-shared.handlebars
N8N_UM_EMAIL_TEMPLATES_INVITE=/opt/n8n/templates/user-invited.handlebars
N8N_UM_EMAIL_TEMPLATES_PROJECT_SHARED=/opt/n8n/templates/credentials-shared.handlebars
N8N_UM_EMAIL_TEMPLATES_PWRESET=/opt/n8n/templates/password-reset-requested.handlebars
N8N_UM_EMAIL_TEMPLATES_WORKFLOW_SHARED=/opt/n8n/templates/workflow-shared.handlebars

Important notes from the documentation:

  • Relative paths are not supported
  • Paths must resolve correctly at startup

4. Restart the Fargate task (mandatory)

n8n loads email templates only during startup.

Any change to:

  • template files
  • mount points
  • environment variables

requires a full task restart.


5. Check file permissions

Ensure the templates are readable by the n8n process:

chmod 644 *.handlebars

If permissions are incorrect, n8n will again fall back to defaults without logging an error.


How to confirm it’s fixed

  1. Restart the Fargate task
  2. Trigger a password reset or invite email
  3. Verify that:
  • n8n branding is gone
  • Your custom template content is used

Once the files exist at the correct absolute path and are readable, n8n will consistently use them.

I think I have most of that right already so will try changing the file rights, why does it silently fail? I have the logging level at debug so you’d think it’d all be laid bare?

@Neil_Carmichael

n8n loads email templates only once at startup and silently falls back to the defaults if a template file isn’t readable at that moment, even with debug logging enabled. So if permissions or ownership are off, it looks like everything is fine but the template is simply ignored.

The quickest way to unblock this is to confirm the n8n process can actually read the files:

docker exec -it <container> sh
whoami
cat /opt/n8n/templates/password-reset-requested.handlebars

If that fails, fix ownership/permissions (for example chown node:node and chmod 644), restart the task, and the custom emails should be picked up.