Fixing Discourse Email Test Errors: Sendmail Not Found (422 Unprocessable Entity)


Fixing Discourse Email Test Errors: Sendmail Not Found (422 Unprocessable Entity)

Email delivery is the heartbeat of any Discourse forum. Password resets, notifications, digests. When email breaks, users feel it immediately. This post walks through a common Discourse email test failure, explains what the logs are really saying, and shows how to fix it safely, without exposing sensitive server data.


The Error Snapshot (Sanitized)

While testing email from the Disourse admin panel, the following error appears in the logs:

Started POST "/admin/email/test" for xxx.xxx.xxx.xxx at 2025-xx-xx xx:xx:xx +0000
Processing by Admin::EmailController#test as */*
Parameters: {"email_address"=>"admin@***.***"}
Initializing Mail::Sendmail with :arguments of type String is deprecated
Completed 422 Unprocessable Entity
sh: 1: /usr/sbin/sendmail: not found

At first glance, it looks noisy. But each line tells a story.


What’s Actually Going Wrong?

There are two distinct issues, one loud and one quiet.

1. Sendmail Binary Is Missing (Main Cause)

This line is the real blocker:

/usr/sbin/sendmail: not found

Discourse is trying to send mail using Sendmail, but your server does not have it installed. Many modern VPS and Docker-based setups do not include Sendmail by default.

As a result, Discourse cannot hand off the email to the system mailer, so it returns:

422 Unprocessable Entity

Which simply means: “I understand the request, but I cannot process it.”


2. Deprecated Sendmail Arguments (Warning, Not Fatal)

This warning:

Initializing Mail::Sendmail with :arguments of type String is deprecated

Is not the cause of failure. It’s a Ruby deprecation notice and can safely be ignored for now. The missing sendmail binary is what actually breaks delivery.

Think of it as a dashboard warning light, not an engine failure :vertical_traffic_light:


Why This Happens Often on Modern Servers

This issue is common when Discourse is installed on:

  • Docker containers
  • Minimal Ubuntu or Debian servers
  • Cloud VPS instances
  • Servers configured to use SMTP instead of local mail

Discourse defaults to Sendmail if SMTP is not explicitly configured.


Solution Option 1: Configure SMTP (Recommended)

The best practice solution is to use SMTP instead of Sendmail.

Examples include:

  • Gmail SMTP
  • Office365
  • Mailgun
  • SendGrid
  • Amazon SES
  • Your hosting provider’s SMTP

What to Do

  1. Log in to Discourse Admin

  2. Go to Settings → Email

  3. Disable Sendmail

  4. Enable SMTP

  5. Enter your SMTP details:

    • Server
    • Port
    • Username
    • Password
    • TLS/SSL
  6. Save settings

  7. Click Test Email

:white_check_mark: This avoids OS-level mail dependencies entirely.


Solution Option 2: Install Sendmail (Quick Fix)

If you prefer system-level mail delivery, install Sendmail on the server.

On Ubuntu/Debian-based systems:

sudo apt update
sudo apt install sendmail

After installation, confirm:

which sendmail

Expected output:

/usr/sbin/sendmail

Restart Discourse afterward, then test email again.

:warning: Note: This approach is less flexible and harder to debug than SMTP.


How to Confirm the Fix Worked

When the issue is resolved:

  • Email test completes successfully
  • No 422 Unprocessable Entity
  • No /usr/sbin/sendmail: not found error
  • Email arrives in the inbox

Discourse logs will be quiet. Quiet logs are happy logs :seedling:


Final Thoughts

This error looks intimidating, but the fix is straightforward once you decode the message. In short:

  • Discourse tried to use Sendmail
  • Sendmail wasn’t installed
  • Email failed
  • SMTP configuration is the cleanest solution

If you’re running Discourse in Docker or on a modern VPS, SMTP is the right path.


1. SMTP Environment Variables (Linux / Docker)

If you’re running Discourse in Docker, you can configure SMTP using environment variables:

DISCOURSE_SMTP_ADDRESS=smtp.example.com
DISCOURSE_SMTP_PORT=587
DISCOURSE_SMTP_USER_NAME=your_username@example.com
DISCOURSE_SMTP_PASSWORD=your_password
DISCOURSE_SMTP_ENABLE_STARTTLS=true
DISCOURSE_SMTP_AUTHENTICATION=login
DISCOURSE_NOTIFICATION_EMAIL=notifications@example.com

Explanation of key variables:

  • DISCOURSE_SMTP_ADDRESS → The SMTP server host (e.g., smtp.gmail.com, smtp.sendgrid.net).
  • DISCOURSE_SMTP_PORT → Common ports: 587 (TLS), 465 (SSL), 25 (plain).
  • DISCOURSE_SMTP_USER_NAME → The login username for the SMTP server.
  • DISCOURSE_SMTP_PASSWORD → The SMTP password or API key.
  • DISCOURSE_SMTP_ENABLE_STARTTLStrue to enable TLS.
  • DISCOURSE_SMTP_AUTHENTICATION → Usually login or plain.
  • DISCOURSE_NOTIFICATION_EMAIL → Email address used as “From” for notifications.

2. Setting SMTP for Discourse in Admin Panel

If you’re not using Docker, or prefer the GUI:

  1. Log in to Discourse as Admin.
  2. Navigate to: Admin → Settings → Email.
  3. Fill in the SMTP settings:
Field Example
SMTP server address smtp.gmail.com
SMTP port 587
SMTP user name your.email@gmail.com
SMTP password your Gmail App Password
Enable STARTTLS true
Authentication login
Notification email notifications@yourdomain.com
  1. Click Save and then Send Test Email.

3. Notes

  • Gmail / Google Workspace: Use an App Password if 2FA is enabled. Regular passwords won’t work.
  • SendGrid / Mailgun / AWS SES: Use the API key as the SMTP password.
  • Firewall: Ensure outgoing connections to the SMTP server port are allowed.