The bounce comes back in seconds, and nothing about it says spam folder. Outlook refused the message before anyone could junk it:
550 5.7.515 Access denied, sending domain example.co.ke does not meet the required authentication level.
That is Outlook rejecting your mail because the sending domain failed its SPF, DKIM and DMARC check, and the fix lives in DNS, not in anybody's mail client. CloudSpinx sets up and runs business email for organizations in Kenya, on Microsoft 365, Google Workspace and mail servers we build ourselves, and this check is the first thing we read on any domain that has started bouncing. The usual cause is a setup where every individual check passes, and a survey further down shows how unevenly even Kenya's 39 licensed banks have set the same records.
What 550 5.7.515 checks, and who it applies to
It applies to a domain sending more than 5,000 messages a day to Outlook.com, Hotmail and Live addresses, Microsoft's consumer service. Every message from that domain must pass SPF, pass DKIM, and sit under a DMARC record of at least p=none that aligns with one of them. Miss any of the three and the message is refused with the code above. Microsoft's announcement sets the requirements out, and its 29 April 2025 amendment is where the rejection code comes from.
Two details catch people. This is the consumer service, so mail to a company's Microsoft 365 tenant is judged by that tenant's own filtering rather than by this rule, which is why the same invoice can bounce from a customer's hotmail.com address and arrive at their office one. And Microsoft's own post contradicts itself on timing, announcing rejection from 5 May 2025 in one paragraph and junk-folder routing first in the next. If you are holding the bounce, that argument is over for your domain.
Plenty of Kenyan organizations cross 5,000 a day without thinking of themselves as bulk senders. A SACCO running month-end statements. A school emailing fee reminders to every parent. An online shop's order confirmations, or the ERP that mails every invoice it raises.
Why SPF and DKIM pass and DMARC still fails
The failure we find most often is not a missing record. It is a platform sending as you under its own identity. Your billing system, newsletter tool or payment gateway sends from [email protected], but the envelope sender is one of its own bounce addresses and its DKIM signature carries its own domain. SPF passes, for the platform. DKIM passes, for the platform. DMARC asks whether either pass belongs to the domain in the From line, and it does not.
Relaxed alignment, the default, accepts your own subdomains: a signature from mail.example.co.ke aligns with example.co.ke. A signature from the platform's domain never does, however valid it is.
You can watch it happen. Send one invoice from the platform to a Microsoft 365 mailbox you control, which stamps the result instead of refusing, and open the message source:
Authentication-Results: spf=pass (sender IP is 198.51.100.24)
smtp.mailfrom=bounce.mailer.example.net; dkim=pass (signature was verified)
header.d=mailer.example.net; dmarc=fail action=none
header.from=example.co.ke; compauth=fail reason=001
Three domains matter: smtp.mailfrom, header.d and header.from. When header.from matches neither of the other two (your own subdomains count as a match), that platform is the one failing. action=none only means your DMARC record asked for nothing. Outlook's bulk-sender rule tests the alignment itself, so a p=none domain gets the 5.7.515 anyway.
The fix sits on the platform's settings page, usually under domain authentication or custom DKIM. It hands you one or two records, a CNAME or a TXT key, to publish under your domain, and from then on it signs as d=example.co.ke. Microsoft asks for one aligned pass. Get DKIM aligned on every platform and SPF alignment stops mattering, which is useful, because an SPF record that needs more than ten DNS lookups returns an error instead of a pass, and every platform you include spends at least one.
Gmail wants the same records, plus one you cannot publish
Google's sender guidelines bind everyone who sends to a Gmail address, at any volume: SPF or DKIM, a TLS connection, a spam rate under 0.3% in Postmaster Tools, and a PTR record on the sending IP that resolves to a hostname which resolves back to that IP. Above 5,000 a day it wants both SPF and DKIM, DMARC at p=none or stronger, alignment, and one-click unsubscribe on marketing mail. Its rejection reads 5.7.26.
The PTR record is what stalls self-hosted mail here, because it is not yours to publish. A reverse record lives in the zone of whoever holds the IP block. On a business fiber line that is the ISP, in a datacenter it is the hosting provider, and no amount of time in your registrar's DNS panel will change it. It is a support ticket, raised before the server is built, which is when we settle it on every self-hosted Zimbra mail server we install, together with the blocklist history of the address itself.
If running your own mail is still an open question, the cost of Zimbra against Microsoft 365 is the place to start. Under about 50 mailboxes with no residency requirement, the hosted suite wins and the PTR problem is somebody else's.

How Kenya's 39 licensed banks set DMARC
We wanted to know how far above Microsoft's floor the organizations with the most reason to care actually sit, so we looked. The population is every institution in the Central Bank of Kenya's directory of licensed commercial banks and mortgage finance institutions, 38 banks and one mortgage lender. For each we took the domain of the contact address CBK lists, used the website domain in the two cases where that address was an ISP mailbox or a domain that does not exist, and read the DMARC record it publishes.
- p=reject
- p=quarantine
- p=none
- no DMARC record
Squares marked sp enforce on the main domain and set sp=none, which exempts every subdomain, including made-up ones, because none of the 39 records sets np. The two marked with a percentage carry pct, a tag RFC 9989 removed because receivers applied it inconsistently.
Thirteen publish p=reject, the setting that tells a receiver to refuse a forgery outright. Seventeen publish p=quarantine. Six publish p=none and three publish nothing. Against Microsoft's bar, 36 of 39 clear the DMARC part, and the other three would meet the bounce at the top of this page the day they send statements to Hotmail addresses at volume from that domain.
Against protection, the count runs the other way. p=none passes Microsoft and stops nothing: RFC 9989, which replaced the original DMARC specification in May 2026, defines it as the domain owner offering "no expression of preference". Add the three with no record and 9 of 39 publish nothing that asks a receiver to refuse mail forged in their name. Six of the enforcing domains also set sp=none, and two still carry a pct value the current standard has dropped.
Getting a bank to reject is slow work, because every system that sends as the bank has to be found and aligned first, and that is weeks of reading reports. Which is the point. If one licensed bank in three has reached p=reject, a domain somebody set up for your business years ago is very likely sitting at p=none, or at nothing, and a forged invoice in its name reaches the receiver with no instruction to stop it. Check yours from any Linux or macOS terminal, where the first answer is your DMARC policy and the second your SPF record:
$ dig +short TXT _dmarc.example.co.ke
"v=DMARC1; p=none; rua=mailto:[email protected]"
$ dig +short TXT example.co.ke | grep spf1
"v=spf1 include:spf.protection.outlook.com -all"
An empty first answer means no DMARC record at all. On Windows, nslookup -type=TXT _dmarc.example.co.ke asks the same question. A domain at reject is also the cheapest anti-phishing control there is, which is why the same work runs through our cybersecurity engagements and not only the email ones.
Setting up SPF, DKIM and DMARC without bouncing your own invoices
Flip the policy first and you bounce your own invoices. This order does not:
- List every system that sends as your domain. The mail platform, the ERP or billing system, the newsletter tool, the payment gateway's receipts, the website's contact form, the office scanner that emails PDFs. The one nobody remembers is the one that breaks.
- Publish DMARC at
p=nonewith aruaaddress someone reads, or a report service that reads it for you. The large receivers send aggregate reports, usually daily, naming every source that sent as you. - Align each sender, DKIM first. Custom DKIM on every platform that offers it, an SPF include only where a platform uses your domain in the envelope, and SPF kept under ten lookups.
- Get the PTR record set on any server you run yourself, matching the name it announces in HELO.
- Step the policy to quarantine, then reject, once the reports show nothing legitimate failing. Leave
spout so subdomains inherit the policy, neversp=none, and skippct, which RFC 9989 removed because receivers applied any value other than 0 or 100 inconsistently. - Keep reading the reports. The next SaaS tool somebody signs up for will send as you without asking, and the report is the only place it shows up.
That sequence is standard on every email engagement we run, on Microsoft 365 or Google Workspace as much as on Zimbra. If you are holding a 5.7.515 bounce, send it with the domain through the quote form on our email page, or on WhatsApp at +254 713 403 044, and we will scope the move to reject with you. The quote is free and commits you to nothing.