Summary
SMTPConfiguration.Validate() (introduced in v2.189.0) fatally errors at startup when GOTRUE_SMTP_HEADERS contains invalid JSON, which crash-loops the entire auth service. Disabling SMTP at the dashboard level does not help — the value is parsed regardless. Currently affecting our production Supabase project — all auth endpoints (/token, /authorize, /user) return Envoy 503 (ECONNREFUSED, x-envoy-attempt-count: 6), while /health and /settings still respond because they don't go through GoTrue.
Reproducing
Set GOTRUE_SMTP_HEADERS to anything that's invalid JSON (e.g. contains \$, which is what's currently being injected into our project by Supabase's platform layer):
GOTRUE_SMTP_HEADERS='{"X-SES-Message-Tags":["…=\$messageType"]}'
Auth fails to boot with:
{"level":"fatal","msg":"Failed to load configuration: conf: SMTP headers not a map[string][]string format: invalid character '$' in string escape code"}
Reference (v2.189.0):
This same code is unchanged in rc2.190.0-rc.6.
Why this is a problem
- SMTP custom headers are an optional feature. A malformed value here shouldn't take down sign-in, refresh-token, OAuth, MFA, and every other auth flow. Fail-closed on auth core, fail-open on cosmetic email metadata.
- The value is often platform-injected, not user-set. On Supabase-hosted projects, the customer can't see or write to this env var via the dashboard or the public Management API — there's no
smtp_headers field in the documented PATCH /v1/projects/{ref}/config/auth schema. So when the platform-injection layer ships a bad value (as is happening for us right now), customers cannot self-recover.
- Disabling SMTP doesn't gate the parse.
Validate() parses headers whenever c.Headers != "", regardless of whether Host/User/Pass are set or whether the SMTP toggle is on.
Proposed fix
In internal/conf/configuration.go, change SMTPConfiguration.Validate() to log a warning and skip the headers feature instead of returning a fatal error:
func (c *SMTPConfiguration) Validate() error {
headers := make(map[string][]string)
if c.Headers != "" {
if err := json.Unmarshal([]byte(c.Headers), &headers); err != nil {
// Don't crash the auth service over an optional feature.
// Log and continue without custom headers.
logrus.WithError(err).Warn("conf: SMTP headers not a valid map[string][]string; ignoring")
headers = nil
}
}
if len(headers) > 0 {
c.normalizedHeaders = headers
}
mail := gomail.NewMessage()
c.fromAddress = mail.FormatAddress(c.AdminEmail, c.SenderName)
return nil
}
Optionally also gate on c.Host != "" so the headers aren't parsed when SMTP is disabled entirely.
Impact for us, right now
100% of authentication is broken for our production project. I've filed a support ticket asking Supabase to clear/correct the platform-injected value, but I'm filing this here because:
- The injected-value bug likely affects every project upgraded to v2.189.0 with the SES/Postmark headers default that has the same malformed value.
- The current
Validate() design makes a recoverable misconfiguration into a total auth outage — that's worth fixing regardless of whether the platform issue is fully resolved.
Environment
- GoTrue version: v2.189.0 (also reproduces against
rc2.190.0-rc.6)
- Supabase-hosted (West US — North California region)
- Started: ~2026-05-15 ~16:00 UTC
Happy to send a PR with the Validate() fix if it would help. Thanks.
Summary
SMTPConfiguration.Validate()(introduced in v2.189.0) fatally errors at startup whenGOTRUE_SMTP_HEADERScontains invalid JSON, which crash-loops the entire auth service. Disabling SMTP at the dashboard level does not help — the value is parsed regardless. Currently affecting our production Supabase project — all auth endpoints (/token,/authorize,/user) return Envoy 503 (ECONNREFUSED,x-envoy-attempt-count: 6), while/healthand/settingsstill respond because they don't go through GoTrue.Reproducing
Set
GOTRUE_SMTP_HEADERSto anything that's invalid JSON (e.g. contains\$, which is what's currently being injected into our project by Supabase's platform layer):Auth fails to boot with:
Reference (v2.189.0):
Headers stringfield)Validate()returns a hard error)This same code is unchanged in
rc2.190.0-rc.6.Why this is a problem
smtp_headersfield in the documentedPATCH /v1/projects/{ref}/config/authschema. So when the platform-injection layer ships a bad value (as is happening for us right now), customers cannot self-recover.Validate()parses headers wheneverc.Headers != "", regardless of whetherHost/User/Passare set or whether the SMTP toggle is on.Proposed fix
In
internal/conf/configuration.go, changeSMTPConfiguration.Validate()to log a warning and skip the headers feature instead of returning a fatal error:Optionally also gate on
c.Host != ""so the headers aren't parsed when SMTP is disabled entirely.Impact for us, right now
100% of authentication is broken for our production project. I've filed a support ticket asking Supabase to clear/correct the platform-injected value, but I'm filing this here because:
Validate()design makes a recoverable misconfiguration into a total auth outage — that's worth fixing regardless of whether the platform issue is fully resolved.Environment
rc2.190.0-rc.6)Happy to send a PR with the
Validate()fix if it would help. Thanks.