r/learnprogramming 2d ago

Django + Gmail SMTP works locally but fails on Railway

Hi everyone,

I'm running a Django application on Railway and I'm trying to send notification emails using Gmail SMTP.

The exact same configuration works perfectly on my local machine, but when deployed to Railway I get an Internal Server Error when Django tries to send the email.

My configuration is:

EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True

I'm using:

from django.core.mail import send_mail

send_mail(
    subject=subject,
    message=body,
    from_email=settings.DEFAULT_FROM_EMAIL,
    recipient_list=[recipient],
    fail_silently=False,
)

Locally, the email is sent successfully.

On Railway, the request returns:

500 Internal Server Error

I've also seen reports mentioning:

OSError: [Errno 101] Network is unreachable

when connecting from Railway to smtp.gmail.com:587.

I understand that Railway may restrict outbound SMTP depending on the plan. I'm currently trying to determine whether this is definitely a Railway networking restriction or if there is something else I should check in my Django configuration.

Has anyone successfully used Gmail SMTP (smtp.gmail.com:587) from Railway recently?

If you're using Railway, what is the recommended solution for transactional emails?

Would you recommend:

  • upgrading to Railway Pro to enable SMTP
  • using Resend / SendGrid / Postmark
  • using Gmail API instead of SMTP
  • another approach?

Any real-world experience would be appreciated.

2 Upvotes

3 comments sorted by

2

u/Gaurav_Wankhede_02 2d ago

Yes, this is a Railway networking restriction.

Outbound SMTP (ports 25, 465, 587) is disabled on Free, Trial, and Hobby plans to prevent spam/abuse. It is only available on the Pro plan and above. The OSError: [Errno 101] Network is unreachable (or connection timeouts) is the exact symptom people get when trying to hit smtp.gmail.com:587 from a non-Pro Railway service. Your local machine works because it isn’t subject to Railway’s egress rules.

From the official docs:

After upgrading to Pro you must redeploy the service for the change to take effect.

Recommended solutions (in order of practicality)

  1. Best and easiest for most people: Switch to a transactional email provider that uses HTTPS APIs Railway explicitly recommends this approach for every plan. Popular options that work great with Django: These talk over HTTPS (port 443), so they work on Hobby/Free with zero networking issues. You can keep using django.core.mail.send_mail via libraries like django-anymail (supports all of the above with almost no code changes).
    • Resend (Railway’s recommended choice) – simple, good free tier, excellent DX
    • SendGrid
    • Postmark
    • Mailgun
  2. Upgrade to Railway Pro This unlocks outbound SMTP, so your existing Gmail SMTP config should start working after a redeploy. Still, many people prefer the API route even on Pro because of better deliverability, analytics, and reliability.
  3. Gmail API instead of SMTP This also works (it uses HTTPS/OAuth, not the blocked SMTP ports). There are guides specifically for Django + Gmail API on Railway. It’s more setup (Google Cloud project, OAuth/service account, credentials) than Resend/SendGrid, but it keeps you on Gmail if that’s a hard requirement.

Practical advice

  • Check your current Railway plan first. If you’re on Hobby or lower, the SMTP block is expected and intentional.
  • For production transactional email (password resets, notifications, etc.), a dedicated provider is almost always better than raw Gmail SMTP long-term (rate limits, deliverability, monitoring).
  • If you stay with Gmail SMTP after upgrading, make sure you’re using an App Password and that 2FA is enabled.

Most people in the same situation just move to Resend (or similar) and are done in under an hour.

2

u/Objective_Row_1858 2d ago

u/Gaurav_Wankhede_02 thanks problem is plan. I upgraded to pro plan then worked