Magento 2.3.3 added native SMTP support, so an extension is no longer required to send order confirmations, invoices and shipment notices through an authenticated relay. The settings have no admin UI, which is why most guides still recommend a paid module — they are set from the command line instead.
| Setting | Value |
|---|---|
| SMTP host | smtp.postwing.app |
| Port | 587 |
| Encryption | STARTTLS (the connection is upgraded to TLS before login) |
| Username | The login of an SMTP token for your domain |
| Password | The password of that token — shown once, when the token is created |
# Transport and host
bin/magento config:set system/smtp/transport smtp
bin/magento config:set system/smtp/host smtp.postwing.app
bin/magento config:set system/smtp/port 587
bin/magento config:set system/smtp/auth login
bin/magento config:set system/smtp/ssl tls # 'tls' = STARTTLS, 'ssl' = port 465
# Credentials — --lock-env writes to env.php instead of the database
bin/magento config:set --lock-env system/smtp/username 'token-login@your-domain.com'
bin/magento config:set --lock-env system/smtp/password 'your-token-password'
bin/magento cache:flushcore_config_data table — and therefore in every database dump, backup and staging copy. --lock-env writes it to app/etc/env.php, which belongs to the deployment rather than the data. Magento sends as five separate identities — General, Sales, Support, Custom 1 and Custom 2 — and a fresh install leaves most of them pointing at example.com. Every one must be on your verified domain or that identity's mail will fail DMARC:
# The five sender identities Magento sends as. Point them all at your domain.
bin/magento config:set trans_email/ident_general/email noreply@your-domain.com
bin/magento config:set trans_email/ident_general/name 'Acme'
bin/magento config:set trans_email/ident_sales/email orders@your-domain.com
bin/magento config:set trans_email/ident_sales/name 'Acme Orders'
bin/magento config:set trans_email/ident_support/email support@your-domain.com
bin/magento cache:flushThe same values are editable under Stores → Configuration → General → Store Email Addresses.
Magento does not send order emails during checkout. It queues them and a cron job delivers them, so on a store where cron is misconfigured the customer never receives a confirmation even though SMTP is set up correctly:
# Confirm cron is actually running — queued sales emails depend on it
bin/magento cron:run --group=default
php bin/magento queue:consumers:listWhile debugging, it is easier to take cron out of the picture:
# Magento queues sales emails by default and sends them from cron.
# For a low-volume store, sending them inline is simpler to debug.
bin/magento config:set sales_email/general/async_sending 0
bin/magento cache:flush| Symptom | Cause and fix |
|---|---|
| No order emails, no errors | Cron is not running. Check cron_schedule and the consumers. |
| Settings have no effect | Config cache not flushed. Run bin/magento cache:flush. |
| Authentication failed | Wrong credentials, or system/smtp/auth not set to login. |
| Connection timeout | Outbound port blocked. Use 8587 or 8465. |
| Some emails arrive, others go to spam | One of the five sender identities is still on a foreign domain. |
| An SMTP extension is also installed | It overrides the native transport. Disable one of the two. |
Yes, since Magento 2.3.3. The system/smtp configuration paths — transport, host, port, auth, ssl, username and password — are built in. There is no admin UI for most of them, so they are set with bin/magento config:set. Extensions such as Mageplaza SMTP mainly add a settings screen and an email log on top of the same mechanism.
By default Magento queues sales emails and sends them from a cron job, so if cron is not running they simply accumulate. Check that the default cron group runs, or set sales_email/general/async_sending to 0 to send them inline while you debug.
Yes. Without it the value is written to the core_config_data table, where it ends up in every database dump and staging copy. --lock-env writes to app/etc/env.php instead, which stays with the deployment rather than the data.
Use tls with port 587, which selects STARTTLS, or ssl with port 465 for implicit TLS. Leaving ssl empty disables encryption entirely and the connection will be refused.
Magento has five separate sender identities under Store → Configuration → General → Store Email Addresses, and a fresh install leaves several pointing at example.com or at whatever address the installer used. Every one of them must be on the domain you verified.
var/log/system.log and var/log/exception.log carry the transport errors. Enabling developer mode with bin/magento deploy:mode:set developer makes them considerably more detailed.