Keycloak Not Sending Emails? How to Fix It

Guilliano Molaire Guilliano Molaire 10 min read

Last updated: June 2026

Keycloak sends email — for account verification, password resets, OTP codes, and admin notifications — only when you have configured valid SMTP settings under Realm Settings > Email in the admin console. The most common reasons email stops working are a missing or incorrect SMTP host or port, the wrong TLS toggle for the port you chose, failed SMTP authentication (almost always because you need a provider-specific app password rather than your account password), or a missing “From” address. Before digging through server logs, use the Test Connection button on the Email tab to isolate the problem immediately.

Where Keycloak Configures Email

In Keycloak 26.x, each realm manages its own outgoing email settings independently. There is no global SMTP configuration shared across realms — every realm you operate must be configured separately.

To reach the email settings, open the Keycloak admin console, select your realm from the realm selector in the top-left corner, then navigate to Realm Settings > Email.

If you are managing multiple realms and email works in one but not another, the SMTP configuration for the non-working realm is almost certainly blank or misconfigured. See our Keycloak realm export and import strategy for how to keep realm settings consistent across environments.

Required Fields in the Email Tab

Every field on the Email tab exists for a reason. Missing or incorrect values are the source of most email failures.

Host — The hostname or IP address of your SMTP server. Examples: smtp.gmail.com, smtp.sendgrid.net, email-smtp.us-east-1.amazonaws.com. Do not include smtp:// as a prefix — Keycloak adds the protocol internally.

Port — The TCP port your SMTP server listens on. This must match the encryption method you select (see the port matrix below).

From — The sender email address that appears in the “From” field of every message Keycloak sends. This field is required. If it is blank, Keycloak will refuse to send email regardless of how correct your SMTP credentials are. The address must also be authorized to send on the SMTP account you are authenticating with; many providers reject mail where the envelope-from does not match the authenticated user.

From Display Name — An optional human-readable label shown alongside the From address, such as Skycloak Identity or your company name.

Reply To and Reply To Display Name — Optional. If set, replies from users go to this address instead of the From address.

Enable SSL and Enable StartTLS — These two checkboxes control how Keycloak negotiates TLS with your SMTP server. They are not interchangeable. Selecting the wrong one for your port is one of the most common configuration mistakes (see below).

Authentication — Toggle this on to reveal Username and Password fields. Most modern SMTP providers require authentication. Leave it off only for relay servers on private networks that do not require credentials.

For a full walkthrough of every field with example values for common providers, see the Keycloak email configuration guide.

The Port and Encryption Matrix

Choosing the wrong port for the encryption method you enabled — or vice versa — results in a connection that hangs, times out, or returns a protocol error. The correct combinations are:

Port Encryption setting Use case
25 Neither SSL nor StartTLS Unauthenticated relay on a private network. Not suitable for internet-facing SMTP.
465 Enable SSL (checked) SMTP over implicit TLS (SMTPS). The TLS handshake happens before any SMTP commands.
587 Enable StartTLS (checked) SMTP with STARTTLS (opportunistic upgrade). The connection starts plain and upgrades to TLS.

A frequent mistake is checking Enable SSL while entering port 587, or checking Enable StartTLS while entering port 465. Both produce connection errors that look identical in the admin console — “Failed to send email” — but stem from a protocol mismatch rather than a credential problem.

Port 25 is blocked by most cloud providers (AWS, GCP, Azure) to prevent spam. If you are self-hosting Keycloak on a cloud VM and see connection timeouts on port 25, the port is almost certainly blocked at the network level. Switch to 587 with StartTLS.

Provider-Specific Gotchas

Different SMTP providers have requirements that are not obvious from generic documentation. These are the most common ones.

Gmail and Google Workspace

Google disabled “less secure app access” for all accounts in 2022. Your Google account password will not work as the SMTP password in Keycloak. You must generate an app password.

To create a Gmail app password:

  1. Enable two-factor authentication on the Google account you want to use for sending.
  2. Go to Google Account > Security > 2-Step Verification > App passwords.
  3. Create a new app password, selecting “Mail” and “Other (custom name)” for the device.
  4. Copy the 16-character password and paste it into the Keycloak SMTP Password field.

Use smtp.gmail.com on port 587 with Enable StartTLS checked. The username is the full Gmail address (e.g., [email protected]). The From address must match this Gmail address exactly, or Google will reject the message.

Google Workspace accounts follow the same process. The app password is generated from the user’s Google account, not from the Workspace Admin console.

SendGrid

SendGrid uses API keys as SMTP passwords. The SMTP username is always the literal string apikey — not your SendGrid account email. The password is the API key you generate in the SendGrid dashboard under Settings > API Keys.

Use smtp.sendgrid.net on port 587 with Enable StartTLS checked. Ensure the API key has “Mail Send” permission enabled.

The From address must be a verified sender in your SendGrid account (either a verified single sender or a verified domain). Unverified sender addresses are rejected silently in some SendGrid plans.

Mailgun

Mailgun SMTP credentials are per-domain and found under Sending > Domains > {your domain} > SMTP credentials in the Mailgun dashboard. The username is typically postmaster@{your-domain} and the password is the auto-generated SMTP password (not your Mailgun account password).

Use smtp.mailgun.org on port 587 with Enable StartTLS checked.

AWS SES

AWS SES SMTP credentials are IAM-based and must be generated specifically for SMTP — they are not your AWS access key and secret directly. In the SES console, go to Account dashboard > Create SMTP credentials to generate a username and password that work with the SES SMTP interface.

The SMTP endpoint varies by region (e.g., email-smtp.us-east-1.amazonaws.com). Use port 587 with Enable StartTLS.

AWS SES places new accounts in sandbox mode by default. In sandbox mode, you can only send to verified email addresses. If Keycloak’s test email reaches your inbox but real user emails do not, your account is likely still in sandbox. Request production access through the SES console.

Ensure the From address is a verified identity in SES (either a verified email address or a verified domain). SES will return a permissions error if the envelope-from is not verified.

The User Must Have an Email Address

This one sounds obvious but is frequently overlooked when Keycloak is integrated with an external identity provider or a SCIM directory.

Keycloak will not send a verification email, password reset link, or OTP to a user who has no email address in their account. If email sending appears to work (test connection succeeds, logs show no errors) but specific users report never receiving messages, check their profile under Users > {user} > Details and confirm the Email field is populated.

Also confirm the realm action that triggers the email is actually enabled. Password reset emails require Reset Password to be enabled under Realm Settings > Login. Verification emails require Verify Email to be enabled. If the action is toggled off, Keycloak will not generate the email regardless of SMTP settings.

For more context on Keycloak user attribute issues, see Keycloak user not found troubleshooting.

Using the Test Connection Button

The Email tab in Keycloak’s Realm Settings includes a Test connection button. This is the fastest way to determine whether your SMTP configuration is correct — use it before looking at server logs.

When you click Test Connection, Keycloak attempts to open a real SMTP connection to the host and port you configured, authenticate with the provided credentials, and send a test message to the email address of the currently logged-in admin user.

If the test succeeds, you will see a green confirmation and the test email will arrive in the admin’s inbox. If it fails, the admin console displays an error message that usually identifies the root cause:

  • “Connection refused” — The host or port is wrong, or a firewall is blocking egress.
  • “Connection timed out” — The port is blocked (common for port 25 on cloud VMs) or the host is unreachable.
  • “535 Authentication failed” — The username or password is incorrect. For Gmail, this almost always means you need an app password.
  • “530 5.7.0 Must issue a STARTTLS command first” — You connected on a STARTTLS port (587) but did not enable StartTLS in Keycloak.
  • “SSL handshake failed” — You have SSL enabled but are connecting to a STARTTLS port, or the server’s TLS certificate is not trusted by the JVM.

Always test after every configuration change. Do not assume a change fixed the problem without verifying.

Checking Server Logs for SMTP Errors

When the admin console error message is not specific enough, Keycloak’s server logs contain the full SMTP exchange including the exact error returned by the remote server.

For Keycloak 26.x running in production or container mode, look for log entries at the ERROR or WARN level from the org.keycloak.email package. In a Docker or Kubernetes deployment:

# Docker
docker logs keycloak-container 2>&1 | grep -i "email|smtp|mail"

# Kubernetes
kubectl logs deployment/keycloak -n keycloak | grep -i "email|smtp|mail"

You can also temporarily increase log verbosity by adding the following to your Keycloak environment configuration:

KC_LOG_LEVEL=org.keycloak.email:DEBUG

The DEBUG level log will show the full SMTP conversation, including the EHLO handshake, AUTH exchange, and any rejection codes from the server. This is particularly useful for diagnosing issues with SES verified identities or Mailgun domain restrictions.

Firewall and Egress Considerations

Even if your SMTP configuration is correct, a network firewall between Keycloak and the SMTP server will prevent delivery.

Common egress scenarios that block email:

  • Port 25 blocked on cloud VMs: AWS, GCP, and Azure all block outbound TCP port 25 by default to prevent spam. There is no workaround other than switching to port 587 or 465.
  • Security group or NSG rules: If Keycloak runs in a VPC (AWS) or VNet (Azure), the security group or network security group must explicitly allow outbound TCP on port 587 or 465 to the SMTP server’s IP range.
  • Kubernetes NetworkPolicy: In Kubernetes deployments with strict NetworkPolicy objects, egress from the Keycloak pod to external IPs may be restricted. Add an allow rule for the SMTP server’s port.

To test TCP connectivity to the SMTP host from the Keycloak server directly:

# Test TCP reachability (run from inside the Keycloak container or VM)
nc -zv smtp.sendgrid.net 587

# Alternatively with curl (available in most container images)
curl -v telnet://smtp.sendgrid.net:587

If the connection is refused or times out, the problem is network-level and no amount of SMTP credential adjustment will fix it.

Symptom, Cause, and Fix Reference

Symptom Likely cause Fix
Test connection times out Port blocked by firewall or wrong port number Check egress rules; switch from port 25 to 587
“535 Authentication failed” Wrong password or account password used instead of app password Generate a provider app password; verify SMTP username format
“530 STARTTLS required” Enable StartTLS is unchecked on port 587 Check Enable StartTLS in Realm Settings > Email
“SSL handshake failed” Enable SSL checked but port is 587, or untrusted certificate Switch to port 465 for SSL, or 587 with StartTLS
Test succeeds but users get no email User has no email address, or realm action is disabled Check user profile; verify action is enabled in Realm Settings > Login
Test succeeds but SES rejects real users SES sandbox mode or unverified sender domain Request SES production access; verify the From domain in SES
Connection refused Wrong SMTP host or host unreachable Confirm hostname; test TCP with nc or curl from the server
Email delivered but goes to spam Unauthenticated sending or SPF/DKIM not configured Configure SPF and DKIM for the From domain; use authenticated SMTP

Frequently Asked Questions

How do I configure SMTP in Keycloak?

In the Keycloak admin console, select your realm, then navigate to Realm Settings > Email. Fill in the SMTP host, port, From address, and authentication credentials. Choose Enable StartTLS for port 587 or Enable SSL for port 465. Click Test connection to verify. Every realm requires its own SMTP configuration — there is no global setting.

Why is Keycloak not sending verification emails?

Keycloak sends verification emails only when two conditions are met: the Verify Email action is enabled under Realm Settings > Login, and the user account has an email address populated. If your SMTP test connection succeeds but verification emails are not sent, check both of these conditions. Also confirm the user did not already verify their email in a previous session.

Which port should I use for Keycloak email?

Use port 587 with Enable StartTLS checked for most modern SMTP providers including Gmail, SendGrid, Mailgun, and AWS SES. Use port 465 with Enable SSL checked if your provider specifically requires implicit TLS. Avoid port 25 on internet-facing deployments — it is blocked by most cloud hosting providers and commonly filtered by ISPs.

Why does Keycloak email work in development but not in production?

The most common reason is that the production environment has stricter egress firewall rules that block outbound SMTP traffic. Verify that your cloud security groups, VPC rules, or Kubernetes NetworkPolicies allow outbound TCP on port 587 or 465. Also confirm that the production SMTP credentials are correct — it is easy to accidentally copy development credentials into a production environment variable.

Can Keycloak send email through OAuth2 or without SMTP?

No. As of Keycloak 26.x, the built-in email provider uses SMTP exclusively. There is no native OAuth2 mail sender (such as Microsoft’s OAuth2 flow for Exchange Online). If your organization has disabled basic auth SMTP in favor of OAuth2 (a common requirement for Microsoft 365), you have two options: use a transactional relay service that still accepts SMTP with API-key authentication (SendGrid, Mailgun, AWS SES), or implement a custom Keycloak email provider using the SPI.

Troubleshoot Faster with Managed Keycloak

Diagnosing SMTP issues across multiple realms and environments is time-consuming. Skycloak’s managed Keycloak platform includes pre-validated email configuration, environment-specific SMTP credential management, and real-time log access — so you spend less time troubleshooting and more time building.

If you are getting started with Keycloak for the first time, the Keycloak getting started guide for 2026 covers the initial setup including realm configuration. For teams that need MFA alongside email-based flows, multi-factor authentication integration patterns for enterprise applications explains how email OTP fits into a broader authentication strategy.

Ready to skip the infrastructure troubleshooting? See Skycloak’s plans and pricing.

Guilliano Molaire
Written by Guilliano Molaire Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Ready to simplify your authentication?

Deploy production-ready Keycloak in minutes. Unlimited users, flat pricing, no SSO tax.

© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman