# Microsoft 365 SMTP AUTH retirement: what breaks, what replaces it

> Password sign-in for smtp.office365.com goes off by default at the end of December 2026. One of Microsoft's two named replacements is itself retiring.

- Published: 2026-10-26
- Author: 28creation Desk
- Format: Analysis
- URL: https://28creation.com/articles/microsoft-365-smtp-auth-basic-retirement/

## The short read

**Microsoft's setup page still sends admins to Azure Communication Services Email, which Microsoft retires on September 30, 2028.**

- Password sign-in for Microsoft 365 SMTP AUTH goes off by default at the end of December 2026. Admins can turn it back on, for now.

### What you can do with this

> Open Reports, then Mail flow, then SMTP AUTH clients in the Exchange admin center, export 90 days, and list every sender marked Basic Auth. Move each one before December.

---

Scanners, line-of-business apps and scripts that send mail through `smtp.office365.com` with a username and password are on a deadline. Microsoft's current timeline says that at the [end of December 2026, SMTP AUTH Basic authentication "will be disabled by default for existing tenants"](https://techcommunity.microsoft.com/blog/exchange/updated-exchange-online-smtp-auth-basic-authentication-deprecation-timeline/4489835). Admins can still turn it back on for now, and Microsoft will announce a final removal date in the second half of 2027.

That leaves about two months to find every device and script that still signs in with a password, and to pick a replacement for each. The choice is harder than Microsoft's own setup page suggests. It names two replacements, and one of them, Azure Communication Services Email, is itself being retired.

We read Microsoft's announcements and documentation on October 22, 2026, and put the dates in one timeline. We also tested an OAuth sending script against a local mock of the server.

## The deadline has moved twice, so check the newest post

Microsoft started removing Basic authentication from Exchange Online [in 2019](https://techcommunity.microsoft.com/blog/exchange/exchange-online-to-retire-basic-auth-for-client-submission-smtp-auth/4114750), and by late 2022 it was gone from every protocol except client submission (SMTP AUTH). In tenants that weren't using SMTP AUTH at all, Microsoft [switched it off as well](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online).

| Date | What Microsoft said |
|---|---|
| April 15, 2024 | Basic auth for SMTP AUTH will be permanently removed in September 2025, with no exceptions |
| Later revision | Rejections start for a small share of submissions on March 1, 2026, and reach 100% on April 30, 2026 |
| January 27, 2026 | New timeline: no change until December 2026 |
| End of December 2026 | Basic auth disabled by default for existing tenants; admins can still enable it |
| After December 2026 | New tenants get no Basic auth by default; OAuth is the supported method |
| Second half of 2027 | Microsoft announces the final removal date |

The first two rows come from the [original April 2024 post](https://techcommunity.microsoft.com/blog/exchange/exchange-online-to-retire-basic-auth-for-client-submission-smtp-auth/4114750), which still carries its revisions; the rest come from the [January 2026 update](https://techcommunity.microsoft.com/blog/exchange/updated-exchange-online-smtp-auth-basic-authentication-deprecation-timeline/4489835). Microsoft's reason: customers "continue to face real challenges modernizing legacy email workflows."

Two things follow. The April 2026 date that some vendor pages still quote is dead. And the 2024 line that Support "cannot re-enable Basic auth for you" no longer fits the first step, because December's change is a default an admin can reverse.

We wouldn't plan around that switch. The January post doesn't say which setting it is or how long it will last, and the final date is still to come.

## What breaks is anything that sends a password to smtp.office365.com

SMTP AUTH is the protocol [devices and applications use to submit mail](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission), usually on port 587. Microsoft lists POP and IMAP clients, "applications, reporting servers, and multifunction devices." Microsoft says virtually all modern mail apps, Outlook and Outlook on the web included, don't use it, so people's own mail keeps working.

The protocol stays; only the password sign-in goes. After the final removal, Microsoft says, a password login gets `550 5.7.30 Basic authentication is not supported for Client Submission.` A scanner that shows that error, or a nightly report that stops arriving, is the symptom to watch for.

Some tenants are already there. SMTP AUTH has been [off by default for organizations created after January 2020](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365). It is also already disabled wherever [security defaults](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission) are on in Microsoft Entra ID.

## The SMTP AUTH report shows who still signs in with a password

The [SMTP AUTH clients report](https://learn.microsoft.com/en-us/exchange/monitoring/mail-flow-reports/mfr-smtp-auth-clients-report) sits under **Reports > Mail flow** in the Exchange admin center. Its table lists each sender address with an **Authentication Protocol** column: "Basic Auth is TlsAuthLogin and Modern Auth is XOAUTH2."

The default view covers 7 days, and the date filter takes a range of up to 90 days. Set 90 and export the CSV, so a monthly or quarterly job shows up too. Every row marked Basic Auth needs one of the replacements below.

## Five replacements, and the one Microsoft is already retiring

Microsoft's [setup page for devices and apps](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365), updated October 5, 2026, names High Volume Email for internal mail. For mail that also goes outside, it names Azure Communication Services Email.

On September 23, 2026, Microsoft [announced the retirement](https://learn.microsoft.com/en-us/azure/communication-services/acs-retirement-and-breaking-changes-guide) of Azure Communication Services as a standalone offering, Email included, effective September 30, 2028. From October 23, 2026, the same guide says, Microsoft limits onboarding to retiring services for customers without an existing resource. It starts with phone numbers and may add more limits "at any time." It recommends migrating existing email workloads off rather than starting new ones.

So the page that tells you what to move to points at a service with an end date. Here are the options on Microsoft's own figures, read October 22, 2026.

| Option | Recipients | Sign-in | Limits | Price |
|---|---|---|---|---|
| SMTP AUTH with OAuth | Inside and outside | OAuth token for a licensed mailbox | 10,000 recipients a day, 30 messages a minute | In the mailbox license |
| Microsoft Graph sendMail | Inside and outside | OAuth, `Mail.Send` permission | Exchange Online limits | In the mailbox license |
| High Volume Email (HVE) | Inside the tenant only | HVE account password or OAuth | No rate limit, 50 recipients a message, 10 MB | $0.000042 per recipient |
| SMTP relay connector | Inside and outside | Static IP address or certificate | "Reasonable limits" | No licensed mailbox needed |
| Azure Communication Services Email | Inside and outside | Entra app secret as the SMTP password | 30 a minute and 100 an hour at the start (custom domain) | $0.00025 per email plus $0.00012 per MB |

## OAuth keeps the same server, if the device can do it

The smallest change keeps `smtp.office365.com` on port 587 and swaps the password for a token. The mailbox limits stay the same: [10,000 recipients a day and 30 messages a minute](https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits), and sent mail lands in Sent Items. The catch is the client. A scanner whose firmware only offers a username and password field can't send a token, and no setting in Microsoft 365 changes that.

For a script or app you control, Microsoft documents a [client credentials flow](https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth) with no signed-in user. In outline:

1. Register an app in Microsoft Entra and add the **SMTP.SendAsApp** application permission from Office 365 Exchange Online, then grant admin consent.
2. Register its service principal in Exchange Online: `New-ServicePrincipal -AppId <APPLICATION_ID> -ObjectId <OBJECT_ID>`. The object ID comes from the Enterprise applications page, not App registrations; Microsoft warns that the wrong one causes an authentication failure.
3. Allow it one mailbox: `Add-MailboxPermission -Identity "reports@contoso.com" -User <SERVICE_PRINCIPAL_ID> -AccessRights FullAccess`.
4. Request a token with the scope `https://outlook.office365.com/.default` and send it in the SASL XOAUTH2 format.

The script below does step 4 with Python's standard library only. Settings come from environment variables, so no secret sits in the file. It exits with an error code on every failure, so a scheduler or a [failure check](/articles/tiny-automation-in-code/) can see that nothing was sent.

```python
#!/usr/bin/env python3
"""Send one message through Exchange Online SMTP AUTH with OAuth (XOAUTH2).
Settings: M365_TENANT_ID, M365_CLIENT_ID, M365_CLIENT_SECRET, M365_SENDER
Usage: python3 send_oauth.py recipient@example.com "Subject" "Body text"
"""
import base64, json, os, smtplib, ssl, sys, urllib.error, urllib.parse, urllib.request
from email.message import EmailMessage
from email.utils import formatdate, make_msgid

SCOPE = "https://outlook.office365.com/.default"


def env(name):
    value = os.environ.get(name)
    if not value:
        sys.exit(f"missing setting {name}")
    return value


def get_token():
    url = f"https://login.microsoftonline.com/{env('M365_TENANT_ID')}/oauth2/v2.0/token"
    form = urllib.parse.urlencode({
        "client_id": env("M365_CLIENT_ID"),
        "client_secret": env("M365_CLIENT_SECRET"),
        "scope": SCOPE,
        "grant_type": "client_credentials",
    }).encode()
    try:
        with urllib.request.urlopen(url, data=form, timeout=30) as resp:
            data = json.load(resp)
    except urllib.error.HTTPError as err:
        try:
            detail = json.loads(err.read() or b"{}").get("error_description", "")[:200]
        except ValueError:
            detail = ""
        sys.exit(f"token request failed: HTTP {err.code} {detail}")
    except urllib.error.URLError as err:
        sys.exit(f"token endpoint unreachable: {err.reason}")
    except ValueError:
        sys.exit("token endpoint did not return JSON")
    if "access_token" not in data:
        sys.exit("token response had no access_token")
    return data["access_token"]


def xoauth2(user, token):
    # base64("user=" + user + "^Aauth=Bearer " + token + "^A^A"), ^A = 0x01
    return base64.b64encode(f"user={user}\x01auth=Bearer {token}\x01\x01".encode()).decode()


def send(to, subject, body):
    if "@" not in to:
        sys.exit(f"not an email address: {to!r}")
    sender = env("M365_SENDER")
    token = get_token()
    msg = EmailMessage()
    msg["From"], msg["To"], msg["Subject"] = sender, to, subject
    msg["Date"], msg["Message-ID"] = formatdate(localtime=False), make_msgid()
    msg.set_content(body)
    ctx = ssl.create_default_context()
    ctx.minimum_version = ssl.TLSVersion.TLSv1_2
    try:
        with smtplib.SMTP("smtp.office365.com", 587, timeout=60) as smtp:
            smtp.ehlo()
            smtp.starttls(context=ctx)
            smtp.ehlo()
            code, reply = smtp.docmd("AUTH", "XOAUTH2 " + xoauth2(sender, token))
            if code != 235:
                sys.exit(f"auth failed: {code} {reply.decode(errors='replace')}")
            smtp.send_message(msg)
    except (OSError, smtplib.SMTPException) as err:
        sys.exit(f"not sent: {err}")
    print(f"sent to {to} as {sender}")


if __name__ == "__main__":
    if len(sys.argv) != 4:
        sys.exit(__doc__)
    send(*sys.argv[1:4])
```

The script asks for a new token on every run, so a scheduled job never reuses an old one. The client secret is different: Entra asks for a [duration when you create it](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). Put its end date in a calendar, because an expired secret stops the mail as quietly as the password it replaced.

## What our test showed, and what it can't show

We have no Microsoft 365 tenant to test against, so we wrote a local mock of the documented behavior. It requires STARTTLS, accepts XOAUTH2 and answers a password login with Microsoft's documented `550 5.7.30` reply. We ran the script against it in eight cases, with four lines changed to point at the mock and trust its test certificate.

| Case | Result |
|---|---|
| Our encoder against Microsoft's published XOAUTH2 example | Same string, byte for byte |
| Correct settings | Sent; the mock recorded one message from the right sender |
| Wrong client secret | Stopped at the token request, exit code 1 |
| Token used for a mailbox the app wasn't granted | `535 5.7.3`, exit code 1 |
| Password login from the same client | `550 5.7.30 Basic authentication is not supported` |
| Mail sent without signing in | Refused by the mock |
| Server unreachable | Exit code 1 with a one-line message |
| Empty recipient | Refused before connecting, exit code 1 |

The last two cases caught bugs in our first draft. An unreachable server crashed it with a Python traceback, the kind of failure that hides in a cron log. An empty recipient printed "sent" and exited 0, because our first mock accepted a message with no recipients. The listing above has both fixes, and the mock now refuses that too.

What the mock can't prove is the Microsoft side: consent, the service principal and the mailbox permission. Send one test message through your own tenant before you switch a production job over.

## Graph and HVE fit code and internal senders

**Microsoft Graph.** For code you write, [`POST /users/{id}/sendMail`](https://learn.microsoft.com/en-us/graph/api/user-sendmail) avoids SMTP entirely. A `202 Accepted` reply means the request was accepted, not delivered, and Exchange Online's limits still apply.

Watch the permission. Granted in Entra, `Mail.Send` as an application permission lets an app "send mail as any user." Microsoft's fix is [RBAC for Applications](https://learn.microsoft.com/en-us/exchange/permissions-exo/application-rbac): assign the `Application Mail.Send` role with a management scope, and remove the tenant-wide consent in Entra, because the two grants add up.

**High Volume Email.** [HVE](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/high-volume-mails-m365) is for apps and devices that mail people inside the company, such as payroll notices, alerts and scan-to-email. It sends only to internal recipients and needs no license. But each HVE account must be tied to a pay-as-you-go billing policy on an Azure subscription, or it can't send at all. The endpoint is `smtp.hve.mx.microsoft` on port 587.

HVE still accepts an account password, which makes it the practical home for an internal-only device that can't do OAuth. The HVE pages we read don't say how long it will keep accepting passwords, so we would treat that as borrowed time too.

## Relay fits office devices that mail customers

**SMTP relay through a connector.** For a device in your own office that mails customers, an inbound connector on your MX endpoint (for example `contoso-com.mail.protection.outlook.com`, port 25) [authenticates by static IP or certificate](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365) instead of a password. It reaches outside recipients and needs no licensed mailbox.

The IP must be static and not shared with another organization, and port 25 must be open. Microsoft also says relay can't be used from a third-party hosted service such as Azure. Direct Send, the unauthenticated method on the same page, can't reach external recipients, and Microsoft says it is working on turning it off by default.

## Azure Communication Services Email has an end date

It still works. Of the five, it is the only one that lets a password-only device reach outside recipients from any network, because the [SMTP password is an Entra app's client secret](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/email/send-email-smtp/smtp-authentication), sent to `smtp.azurecomm.net`. But a new custom domain starts at [30 emails a minute and 100 an hour](https://learn.microsoft.com/en-us/azure/communication-services/concepts/service-limits) until you ask for more, and the service ends on September 30, 2028.

Microsoft lists [$0.00025 per email and $0.00012 per MB](https://learn.microsoft.com/en-us/azure/communication-services/concepts/email-pricing), and notes those example prices may not be the latest. A hypothetical office sending 2,000 messages of 0.2 MB a month, one recipient each, would pay $0.50 plus $0.048 on those figures. The same 2,000 messages to staff through HVE would cost $0.084.

Price isn't the issue with either. The end date is.

## What this means for you

The decision is per sender, and it turns on two questions: can it do OAuth, and does it mail anyone outside the company?

- **Your own scripts and apps:** move them to OAuth on `smtp.office365.com` with the steps above, or to Graph `sendMail`. Nothing else changes, and nothing extra is billed.
- **A device that mails only staff and can't do OAuth:** point it at HVE. Set up the billing policy first, or the account stays inactive.
- **A device that mails customers and can't do OAuth:** use a relay connector if it sits behind a static IP you own or can present a certificate. If it doesn't, replace the device or route it through a mail service you control. We wouldn't start a new setup on Azure Communication Services Email two years before its end date.
- **A sender in the report you can't match to a device:** set `Set-CASMailbox -Identity <mailbox> -SmtpClientAuthenticationDisabled $true` on that one mailbox and see what complains. That turns off SMTP AUTH for that mailbox alone, so you find out in a week you chose instead of in late December.

Start with the 90-day export from the SMTP AUTH clients report. The rows marked Basic Auth are your list. Give each one a replacement and a test date before December, while turning Basic auth back on is still an option rather than the plan.

## How we made this

We read Microsoft's two Exchange Team posts on the SMTP AUTH timeline, the Microsoft Learn pages listed below and the Azure Communication Services retirement guide on October 22, 2026. We wrote the sending script and a local mock of the token endpoint and SMTP server, and ran the eight cases in the table on that date. The mock imitates Microsoft's documented replies; it is not Microsoft's service. We did not test against a real Microsoft 365 tenant, a scanner or the paid HVE and Azure services.

## Sources

- Microsoft Exchange Team, [Updated Exchange Online SMTP AUTH Basic Authentication Deprecation Timeline](https://techcommunity.microsoft.com/blog/exchange/updated-exchange-online-smtp-auth-basic-authentication-deprecation-timeline/4489835) (January 27, 2026)
- Microsoft Exchange Team, [Exchange Online to retire Basic auth for Client Submission (SMTP AUTH)](https://techcommunity.microsoft.com/blog/exchange/exchange-online-to-retire-basic-auth-for-client-submission-smtp-auth/4114750) (April 15, 2024, with later revisions)
- Microsoft Learn, [Deprecation of Basic authentication in Exchange Online](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online)
- Microsoft Learn, [Enable or disable SMTP AUTH in Exchange Online](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission)
- Microsoft Learn, [How to set up a multifunction device or application to send email using Microsoft 365](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365) (updated October 5, 2026)
- Microsoft Learn, [SMTP AUTH clients report in the new EAC](https://learn.microsoft.com/en-us/exchange/monitoring/mail-flow-reports/mfr-smtp-auth-clients-report)
- Microsoft Learn, [Authenticate an IMAP, POP or SMTP connection using OAuth](https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth)
- Microsoft Learn, [Exchange Online limits](https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits)
- Microsoft Learn, [user: sendMail](https://learn.microsoft.com/en-us/graph/api/user-sendmail) and [RBAC for Applications in Exchange Online](https://learn.microsoft.com/en-us/exchange/permissions-exo/application-rbac)
- Microsoft Learn, [Manage High Volume Email for Microsoft 365](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/high-volume-mails-m365)
- Microsoft Learn, [Retirement and breaking changes guide for Azure Communication Services](https://learn.microsoft.com/en-us/azure/communication-services/acs-retirement-and-breaking-changes-guide), [Email pricing](https://learn.microsoft.com/en-us/azure/communication-services/concepts/email-pricing), [Service limits](https://learn.microsoft.com/en-us/azure/communication-services/concepts/service-limits) and [Set up SMTP authentication](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/email/send-email-smtp/smtp-authentication)
- 28creation test, October 22, 2026: the script above, run against a local mock token endpoint and SMTP server with a self-signed certificate, eight cases
