Skip to main content
A self-hosted PostQueen sends no mail until you give it a provider. Without one, password resets report success and send nothing, so a person locked out has no way back in. Set this up before you invite anyone. PostQueen sends password reset links, invitations, one-time sign-in codes when passwordless sign-in is on, activation links when activation is on, and the notification emails each person chooses in Settings > Notifications.

Set up a provider

1

Choose the provider and the sender

EMAIL_PROVIDER must be exactly resend or nodemailer. Any other value, including a typo or no value, selects a provider that sends nothing and reports no error. Both need a sender:
Without both sender values no mail goes out, even with a provider.
2

Add the credentials

Create an account at Resend, verify the domain you send from, and create an API key.
EMAIL_FROM_ADDRESS has to be on the domain you verified, or Resend refuses the mail.
3

Recreate the container

Recreate the app container so it reads the new values. A plain docker restart or docker compose restart keeps the old container and its old environment.In the folder that holds docker-compose.yaml, recreate only the postqueen service:
The database, Redis and Temporal keep running. Avoid docker compose down for a settings change: on a host that runs other Compose services in the same project, it stops them too. On Kubernetes, see Kubernetes with Helm.The backend logs the provider it picked, and any credential it misses:
Email service provider: resend (or nodemailer), with no Missing environment variable line after it.
4

Send a test

Use Forgot password? on the login page with an address you can read. The mail should arrive within a minute.
Most mail goes out through Temporal, on two task queues the orchestrator serves: email for password resets, notifications, billing mail and invites, and email-bulk for digests and welcome mail. The Temporal server limits them to about one and a half emails a second together, across all workers, to stay under Resend’s default rate. A stack without a working Temporal sends none of it. Sign-in codes and activation links are sent directly by the backend instead. If you set EXCLUDE_QUEUE, keep both queues on at least one worker.

Require activation for new accounts

By default a new email-and-password account can sign in at once. To make people confirm their address first:
Activation then applies once mail can actually go out: a provider named in EMAIL_PROVIDER and both sender values. Sign-ups through Google, Apple, GitHub or your own single sign-on skip it, because the provider already vouched for the address.
Finish the provider before you turn activation on. With a provider named but its credentials wrong or missing, for example EMAIL_PROVIDER=resend without RESEND_API_KEY, every new account is created inactive and its activation mail never arrives.

If mail does not arrive

EMAIL_PROVIDER is not exactly resend or nodemailer, or one of the two sender values is missing. The log line Email service provider: shows which provider was chosen; no provider means none.
EMAIL_FROM_ADDRESS is not on a domain verified in your Resend account.
Many hosting providers block outbound mail ports until you ask. Test from the server: nc -zv smtp.example.com 465.
Activation is on and the mail is not getting out. Fix the provider, then have the person request a new activation mail from the login page.
Last modified on October 9, 2026