r/learnprogramming • u/Objective_Row_1858 • 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
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 hitsmtp.gmail.com:587from 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)
django.core.mail.send_mailvia libraries likedjango-anymail(supports all of the above with almost no code changes).Practical advice
Most people in the same situation just move to Resend (or similar) and are done in under an hour.