Sent Verification email Instead of having configured HTML template file, the email body contains the HTML returned by the application URL configured in GOTRUE_SITE_URL.
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- go
- Domain
- authentication
Research direction
Start by reproducing the issue with the self-hosted GoTrue Docker setup, the GOTRUE_MAILER_TEMPLATES_CONFIRMATION path, and GOTRUE_SITE_URL configuration described here; inspect the confirmation email in Mailpit. Compare the configured file-based template with the generated message and verify whether the signup flow using emailRedirectTo selects the URL response instead. Done means the configured template is rendered with variables such as ConfirmationURL, while SITE_URL only affects links and redirects.
Written by the indexing model from the issue text.
Description
Bug report
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
When self-hosting Supabase Auth (GoTrue) and configuring custom email templates via the GOTRUE_MAILER_TEMPLATES_* environment variables, the configured template files appear to be ignored.
Instead of rendering the contents of the configured HTML template file, the email body contains the HTML returned by the application URL configured in GOTRUE_SITE_URL.
In our case:
GOTRUE_SITE_URL=https://app.ometasystems.com
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
The confirmation email body contains the HTML source of:
https://app.ometasystems.com
(which is a React/Vite SPA index page), rather than the contents of:
/etc/gotrue/templates/signup_confirmation.html
The behavior is reproducible with Mailpit and appears to originate from GoTrue rather than the SMTP server.
To Reproduce
Environment
Self-hosted Supabase Auth:
image: supabase/gotrue:v2.189.0
Configure custom template
Mount template directory:
auth:
volumes:
- ./volumes/auth/templates:/etc/gotrue/templates
Configure environment variables:
GOTRUE_SITE_URL=https://app.ometasystems.com
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
GOTRUE_MAILER_TEMPLATES_INVITE=/etc/gotrue/templates/invite.html
GOTRUE_MAILER_TEMPLATES_RECOVERY=/etc/gotrue/templates/reset_password.html
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=/etc/gotrue/templates/magic_link.html
GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE=/etc/gotrue/templates/email_change.html
GOTRUE_MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_INVITE=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_RECOVERY=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=/auth/v1/verify
Template file example:
<html>
<body>
<h1>Confirm Your Account</h1>
<a href="{{ .ConfirmationURL }}">
Confirm Email
</a>
</body>
</html>
Verify template exists inside container:
docker exec -it supabase-auth cat /etc/gotrue/templates/signup_confirmation.html
Output matches the expected template file.
Sign up a user
await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: "https://app.ometasystems.com/auth"
}
})
Observe email
Using Mailpit, the received email body contains the HTML source of:
https://app.ometasystems.com
Example excerpt:
<!doctype html>
<html lang="en">
<head>
<script type="module" src="/@vite/client"></script>
<title>Lovable App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
instead of the configured template content.
Expected behavior
GoTrue should render the email using the configured file:
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
The resulting email body should contain the HTML from the template file with variables substituted (e.g. {{ .ConfirmationURL }}).
The contents of GOTRUE_SITE_URL should only influence generated URLs and redirects, not replace the email template body.
System information
- OS: Ubuntu Server 24.04 LTS
- Deployment: Self-hosted Supabase via Docker Compose
- Auth Image:
supabase/gotrue:v2.189.0 - SMTP: Mailpit
- Browser: Chrome
- Frontend: React + Vite
- Version of supabase-js: latest v2.x (can provide exact version if needed)
- Node.js: 22.x
Additional context
Runtime environment confirms the template variables are correctly set:
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
GOTRUE_MAILER_TEMPLATES_INVITE=/etc/gotrue/templates/invite.html
GOTRUE_MAILER_TEMPLATES_RECOVERY=/etc/gotrue/templates/reset_password.html
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=/etc/gotrue/templates/magic_link.html
GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE=/etc/gotrue/templates/email_change.html
The template files are present inside the running container:
docker exec -it supabase-auth ls -R /etc/gotrue/templates
Output:
email_change.html
invite.html
magic_link.html
reset_password.html
signup_confirmation.html
This appears either to be:
- A regression in
supabase/gotrue:v2.189.0 - An undocumented interaction between
GOTRUE_SITE_URL,emailRedirectTo, andGOTRUE_MAILER_TEMPLATES_* - File-based templates being ignored in favor of a URL-based template source
- Dominant language
- Go
- Stars
- 2.6k
- Forks
- 764
- Avg merge
- 5d 3h
- Merged PRs (30d)
- 39
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from supabase/auth
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 86/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Similar issues
-
optimization optimization:agents-md-curator
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
githubnext/gh-aw-cao#13143 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
blinklabs-io/bursa#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
yanet-platform/ipfw-go#129 ·
-
bug confmap/provider/googlesecretmanagerprovider needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
open-telemetry/opentelemetry-collector-contrib#51273 · 2 comments ·
-
bug: AI Gateway client filter lists "Unknown" twice when NULL and literal Unknown clients coexist Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100