Quick Answer

SPF macros are variables that expand during SPF evaluation. %{s} is the sender email, %{l} is the local-part (before @), %{d} is the sender domain, %{i} is the connecting IP, and %{o} is the HELO domain. Macros enable dynamic SPF lookups—useful for large organizations with per-sender or per-IP authorization needs. Most domains don't need macros; they're for specialized enterprise use cases.

SPF Macros Explained: %{s}, %{l}, %{d}, and More

By Braedon·Mailflow Authority·Email Authentication·Updated 2026-03-31

SPF Macro Basics

Macros are placeholders in SPF records that expand to actual values when the record is evaluated. They enable dynamic authorization based on sender-specific information.

Basic format: %{letter} where the letter represents different data.

Available Macros

MacroExpands ToExample
%{s}Sender email address[email protected]
%{l}Local-part of senderuser
%{d}Domain of senderexample.com
%{i}Connecting IP (dotted/coloned)192.0.2.1
%{o}HELO/EHLO domainmail.example.com
%{p}Validated domain of IP (PTR)mail.server.com
%{v}IP versionin-addr or ip6
%{h}HELO/EHLO domainmail.example.com

Macro Modifiers

You can transform macro values:

ModifierEffectExample
rReverse%{ir} = reversed IP
digitRight-split%{d2} = last 2 parts of domain
digit-rLeft-split%{d2r} = first 2 parts reversed

IP reversal example:

  • %{i} = 192.0.2.1
  • %{ir} = 1.2.0.192

Domain splitting:

  • %{d} = mail.server.example.com
  • %{d2} = example.com (last 2 parts)
  • %{d1} = com (last 1 part)

Common Macro Use Cases

Use Case 1: Per-IP Authorization

Check if the sending IP is specifically authorized via DNS:

v=spf1 exists:%{ir}.spf.example.com ~all

How it works:

  1. Sender connects from 192.0.2.1
  2. %{ir} expands to 1.2.0.192
  3. SPF looks up 1.2.0.192.spf.example.com
  4. If an A record exists → pass

To authorize an IP, create DNS A records:

1.2.0.192.spf.example.com. IN A 127.0.0.2

This scales better than listing hundreds of ip4 mechanisms—each IP gets its own DNS record.

Use Case 2: Per-Sender Authorization

Authorize specific senders dynamically:

v=spf1 exists:%{l}._spf.example.com ~all

How it works:

  1. Email from [email protected]
  2. %{l} expands to sales
  3. SPF looks up sales._spf.example.com
  4. If record exists → pass

To authorize a sender:

sales._spf.example.com. IN A 127.0.0.2

Practitioner note: Per-sender authorization sounds appealing but creates massive DNS management overhead. I've only seen it work at organizations with sophisticated DNS automation. For most, include mechanisms are simpler and sufficient.

Use Case 3: Combining IP and Domain

Authorize IPs per sending domain:

v=spf1 exists:%{ir}.%{d}._spf.authservice.com ~all

How it works:

  1. Sender from 192.0.2.1 claiming customer.com
  2. Expands to 1.2.0.192.customer.com._spf.authservice.com
  3. Central service manages authorization for each customer + IP

This pattern is used by email security providers managing multiple customer domains.

The exists Mechanism

exists is almost always used with macros. It checks if a DNS A record exists (regardless of what IP it returns):

exists:%{i}._spf.example.com
  • If DNS returns any A record (even 127.0.0.1) → mechanism matches → pass
  • If DNS returns NXDOMAIN or empty → no match → check next mechanism

Important: The actual IP address returned doesn't matter. Existence is the only check.

Macro Security Considerations

Macros can create DNS amplification vectors:

# Potentially dangerous - untrusted input in DNS query
exists:%{l}._spf.example.com

An attacker could send emails with malicious local-parts designed to trigger excessive DNS queries or exploit DNS vulnerabilities.

Mitigation:

  • Use macros only with trusted, controlled sender patterns
  • Implement rate limiting on DNS
  • Monitor for unusual query patterns

Debugging Macros

Macro expansion happens during SPF evaluation. To see what a macro expands to:

  1. Check raw headers: Some receivers include macro expansion in Authentication-Results
  2. Test with MXToolbox: Their SPF tool shows expansion for test queries
  3. Manual calculation: Work through the expansion yourself

Example debug:

Record: v=spf1 exists:%{ir}._spf.example.com ~all
Sender IP: 192.0.2.1
Expansion: exists:1.2.0.192._spf.example.com
Query: dig A 1.2.0.192._spf.example.com

When NOT to Use Macros

Don't use macros if:

  • Standard include/ip4 mechanisms work for your use case
  • You don't have DNS automation infrastructure
  • You want simple, auditable SPF records
  • You're not managing large numbers of IPs or senders

Most domains should stick to:

v=spf1 include:_spf.google.com include:sendgrid.net ~all

Simple, readable, easily debugged.

Practitioner note: In 8 years of email consulting, I've implemented macros exactly twice—both for enterprises sending from 500+ IPs with automated provisioning. Everyone else does fine with include statements.

Macro Lookup Costs

Each exists with macros counts as 1 DNS lookup toward the 10-lookup limit. The macro expansion itself is free—the resulting DNS query counts.

v=spf1 exists:%{ir}._spf.example.com exists:%{l}._auth.example.com ~all

This is 2 DNS lookups (2 exists mechanisms).

For the SPF basics, see the SPF setup guide. For understanding all SPF mechanisms, see SPF mechanisms explained. For the lookup limit that macros can help solve, see the SPF 10-lookup limit guide. If you have a complex infrastructure requiring macro-based SPF authorization, schedule a consultation. I'll help design a scalable SPF architecture that works with your DNS management systems.

Sources

  • RFC 7208: Sender Policy Framework (SPF), Section 7 — Macros
  • RFC 7208: Section 8 — Macro Definitions
  • dmarcian: SPF Macros
  • IETF: SPF Specification

v1.0 · March 2026

Frequently Asked Questions

What are SPF macros?

SPF macros are special variables in SPF records that get replaced with actual values during SPF evaluation. For example, %{d} becomes the sending domain, %{i} becomes the sender's IP address.

When should I use SPF macros?

Only in advanced scenarios: large organizations with per-sender authorization, custom IP validation via DNS lookups, or complex multi-tenant environments. Most domains should use standard include and ip4 mechanisms.

What does exists:%{i}._spf.example.com mean?

This checks if a DNS A record exists for the sender's IP address at _spf.example.com. If you're sending from 192.0.2.1, it looks up 1.2.0.192._spf.example.com. If the record exists, SPF passes.

Are SPF macros supported by all receivers?

Yes, macros are part of the SPF specification (RFC 7208). All compliant receivers support them. However, debugging is harder, and misconfiguration can cause unexpected failures.

Do SPF macros count toward the lookup limit?

The exists mechanism with macros counts as 1 DNS lookup per evaluation. The macro expansion itself doesn't add lookups, but the resulting DNS query does.

Want this handled for you?

Free 30-minute strategy call. Walk away with a plan either way.