Install & Compatibility
Where this runs
tested against v1.6.8 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 1.432s · 56.9MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 5.6s · import 1.310s · 57MB
52MB installed
● package 52MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
FastMail
✓ from fastapi_mail import FastMail
MessageSchema
✓ from fastapi_mail import MessageSchema
ConnectionConfig
✓ from fastapi_mail import ConnectionConfig
This quickstart demonstrates how to set up `fastapi-mail` to send an HTML email asynchronously using FastAPI's `BackgroundTasks`. It uses environment variables for sensitive SMTP credentials and defines a simple endpoint to trigger an email send. Remember to replace placeholder values with your actual SMTP server details.
from fastapi import FastAPI, BackgroundTasks
from fastapi_mail import FastMail, MessageSchema, ConnectionConfig
from pydantic import EmailStr
import os
app = FastAPI()
# Configure email connection settings
# It's recommended to use environment variables for sensitive data
conf = ConnectionConfig(
MAIL_USERNAME=os.environ.get("MAIL_USERNAME", "your_email@example.com"),
MAIL_PASSWORD=os.environ.get("MAIL_PASSWORD", "your_password"),
MAIL_FROM=EmailStr(os.environ.get("MAIL_FROM", "your_email@example.com")),
MAIL_PORT=int(os.environ.get("MAIL_PORT", 587)),
MAIL_SERVER=os.environ.get("MAIL_SERVER", "smtp.gmail.com"),
MAIL_FROM_NAME=os.environ.get("MAIL_FROM_NAME", "My FastAPI App"),
MAIL_STARTTLS=bool(os.environ.get("MAIL_STARTTLS", True)),
MAIL_SSL_TLS=bool(os.environ.get("MAIL_SSL_TLS", False)),
USE_CREDENTIALS=bool(os.environ.get("USE_CREDENTIALS", True)),
VALIDATE_CERTS=bool(os.environ.get("VALIDATE_CERTS", True)),
TEMPLATE_FOLDER=None # Path to your Jinja2 templates, e.g., './templates'
)
@app.post("/send-email")
async def send_test_email(email_to: EmailStr, background_tasks: BackgroundTasks):
# Create a message schema
message = MessageSchema(
subject="FastAPI Mail Test",
recipients=[email_to], # List of recipients
body="<p>This is a test email sent from <strong>FastAPI-Mail</strong>!</p>",
subtype="html" # Can be "plain" or "html"
)
# Instantiate FastMail with the configuration
fm = FastMail(conf)
# Send the email using background tasks to avoid blocking the API response
background_tasks.add_task(fm.send_message, message)
return {"message": "Email has been scheduled for sending"}
Debug
Known issues
gotchaSending emails is a blocking I/O operation. To prevent your FastAPI application from freezing, always use `FastMail.send_message` with `BackgroundTasks` for non-blocking execution, or ensure it's `await`ed within an `async` function.fixPass `fm.send_message` to `background_tasks.add_task()` within your FastAPI endpoint, or `await fm.send_message()` in an `async` context.
affects: All versions
gotchaIncorrect SMTP configuration (e.g., `MAIL_PORT`, `MAIL_SERVER`, `MAIL_STARTTLS`, `MAIL_SSL_TLS`, `USE_CREDENTIALS`) is a common cause of connection failures. These settings must precisely match your email provider's requirements.fixDouble-check your SMTP provider's documentation for the correct server, port, and TLS/SSL settings. Experiment with `MAIL_STARTTLS` and `MAIL_SSL_TLS` (they are mutually exclusive and often one implies the other).
affects: All versions
gotchaWhen attaching files, ensure the file pointer for the attachment is reset to the beginning (e.g., using `file_object.seek(0)`) before passing it to `MessageSchema`. Failure to do so might result in empty or malformed attachments.fixBefore creating `AttachmentFile` or `MessageSchema` with a file-like object, call `file_object.seek(0)`.
affects: Prior to v1.6.2 (where an internal fix was made), but still good practice for user-managed file objects.
gotchaThe `redis` dependency is optional. If you intend to use `DefaultChecker` for features like email rate limiting or connection pooling, you must explicitly install `redis` (`pip install redis`) and configure it alongside `fastapi-mail`.fixInstall `redis` separately: `pip install redis`. If using `DefaultChecker` ensure the Redis client is properly initialized and passed to `ConnectionConfig`.
affects: All versions
Errors
Common errors & fixes
SMTPAuthenticationError / SMTPServerDisconnected / Could not connect to SMTP host
These errors typically occur due to incorrect SMTP credentials (username/password), an invalid SMTP server address or port, or the email provider blocking the connection (e.g., Gmail requiring app passwords or enabling less secure app access).
fixVerify the MAIL_USERNAME, MAIL_PASSWORD, MAIL_SERVER, and MAIL_PORT in your ConnectionConfig are correct; if using Gmail or similar providers, generate an app-specific password and use it as MAIL_PASSWORD, and ensure 'less secure app access' is not blocking the connection.
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
This error arises when an environment variable, typically MAIL_PORT, is not found or loaded correctly, causing os.getenv() to return None which cannot be converted to an integer.
fixEnsure your .env file is correctly defined and loaded (e.g., by calling `load_dotenv()` from `python-dotenv`) and that all required numeric environment variables like MAIL_PORT have a value set.
socket.gaierror: [Errno -2] Name or service not known
This error indicates that the hostname specified for the SMTP server (MAIL_SERVER in ConnectionConfig) cannot be resolved into an IP address by the system's DNS.
fixDouble-check the MAIL_SERVER value in your ConnectionConfig for typos, verify network connectivity and DNS settings, or ensure the hostname is correctly configured if it's a local or custom SMTP server.
SMTPRecipientsRefused
This error occurs when the SMTP server refuses to accept one or more of the recipient email addresses, often due to server-side policies, sender address mismatch, or invalid recipient addresses.
fixEnsure that the MAIL_FROM address in your ConnectionConfig is authorized to send emails through your SMTP server and that recipient email addresses are valid and correctly formatted.
Upgrade
Version history
1.6.8latest on PyPI · released Aug 22, 2026
Audit
Dependencies
redisoptionalRequired only if using `DefaultChecker` for features like rate limiting or connection pooling.