{"id":438,"date":"2026-08-23T12:00:00","date_gmt":"2026-08-23T09:00:00","guid":{"rendered":"https:\/\/john-nessime.com\/blog\/?p=438"},"modified":"2026-09-14T16:13:09","modified_gmt":"2026-09-14T13:13:09","slug":"business-email-dns-mx-spf-dkim-dmarc","status":"publish","type":"post","link":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/","title":{"rendered":"Business Email DNS Done Right: MX, SPF, DKIM and DMARC"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The finance manager forwards you a message and asks how it got through. It appears to come from the CEO, it carries the company domain in the From line, and it asks for a bank detail change on an invoice that is genuinely outstanding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So you check the zone. There is an MX record. There is an SPF record. There is a DKIM key published under a selector. There is a DMARC record. You paste the domain into three free checkers and every one of them lights up green.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Everything is configured. The domain is still trivially spoofable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is the failure mode that makes business email DNS worth writing about. It is not that people forget to publish records. It is that publishing a record and enforcing a policy are different acts, the checkers reward the first one, and nothing anywhere in DNS will tell you that you stopped halfway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What follows is what each of the four records actually does, what breaks when it is wrong, the domain architecture decision that stops the problem recurring, and an order of operations that gets you to enforcement without losing legitimate mail on the way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The two jobs your business email DNS actually does<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Almost every confused email ticket traces back to one misunderstanding: people treat these four records as a single feature called &#8220;email setup.&#8221; They are two unrelated systems that happen to share a zone file.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Receiving mail.<\/strong> This is MX, and only MX. Nothing else in the set participates.<\/li><li><strong>Authorizing senders.<\/strong> This is SPF, DKIM and DMARC. None of them affect whether a single message reaches your mailbox.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The consequence is blunt. If inbound mail is not arriving, editing SPF cannot help and never will. If your domain is being spoofed, a perfect MX configuration contributes nothing. It is common to see an afternoon spent rewriting an SPF record for a problem that lived entirely in a mail routing rule.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A third job hides inside the second, and it is the one people skip. SPF and DKIM only produce evidence: this server was authorized, this content was signed by this domain. Neither tells a receiving server what to do when the evidence is missing. Only DMARC does, through its policy tag, and that tag is the single enforcement dial in the whole arrangement.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MX: the only record inbound delivery depends on<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An MX record carries exactly two values: a preference number and a hostname. Lower preference numbers are tried first. Equal preference numbers let a sender spread load across the listed hosts, which is how most hosted mail providers publish theirs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short MX example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The hostname side has two constraints panels will happily let you violate. The target must be a name resolving to A or AAAA records, not an IP typed into the field, and it must not point at a CNAME. Some panels accept an IP and quietly invent a hostname behind the scenes, which works until you move providers and find the record you thought you published is not the one that exists.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If a domain has no MX record at all, the SMTP specification tells senders to fall back to its A or AAAA address. On a business domain that is your web server. The connection times out or is refused, and the sender queues and retries for days before anyone sees a bounce. The mail is not rejected; it is late, sometimes by a working week.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And subdomains do not inherit MX records from the parent. If <code>example.com<\/code> has MX records, <code>mail.example.com<\/code> does not. It falls back to its own A record, or to nothing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Null MX for domains that should never receive mail<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Most businesses own more domains than they use for mail: typo-squat defenses, old brand names, a marketing microsite, the domain from the company they acquired. RFC 7505 defines a way to say &#8220;this domain accepts no mail&#8221; explicitly, using a single MX record with preference 0 and a target of a lone dot.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example-parked.com.  3600  IN  MX  0  .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A conforming sender sees this and rejects immediately instead of falling back to the A record and retrying for days. The bigger benefit is backscatter: when someone forges a return address at a domain of yours, bounce messages get aimed at it. A null MX turns those into an instant rejection at the sender&#8217;s end.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One rule attached to this: a domain advertising a null MX must not publish any other MX records. It is the whole set or nothing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One operational note: drop MX TTLs to a few minutes before a mail migration and raise them afterwards. A low TTL costs a little query volume. A high TTL during a cutover costs you mail delivered to a server you already decommissioned, with no error anywhere to tell you. Per-record TTL control and fast propagation matter here, which is why I would rather do a cutover on something like Cloudflare than a registrar&#8217;s default panel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">SPF: an authorization list with a hard budget<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SPF is a TXT record at the domain apex that begins with <code>v=spf1<\/code> and lists the systems allowed to send with your domain in the envelope sender. Publish two of them and you have published none: the result is a permanent error, which receivers treat as a failure.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short TXT example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The constraint everyone eventually hits is the lookup budget. Evaluation is capped at ten DNS-querying mechanisms. The terms that count are <code>include<\/code>, <code>a<\/code>, <code>mx<\/code>, <code>ptr<\/code>, <code>exists<\/code> and <code>redirect<\/code>, and the count follows nested includes all the way down, so one vendor <code>include:<\/code> can carry four lookups inside it. Literal <code>ip4<\/code> and <code>ip6<\/code> ranges cost nothing, and neither does <code>all<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Exceed ten and evaluation stops with a permanent error. It does not fail open. It does not keep counting and pass anyway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is a second, quieter limit: void lookups, meaning queries that return nothing. Implementations are told to cap those at two. This is the one that bites long after you stop paying attention, because the trigger is a vendor you cancelled whose <code>include:<\/code> target eventually stopped resolving. Your record did not change. Your mail started failing anyway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Over budget, the honest options are to drop vendors you no longer use, replace lookup-heavy mechanisms with the literal IP ranges they resolve to, or move senders onto their own subdomains so each gets a fresh budget. Flattening services that resolve includes and keep the record updated do work, but understand the trade: you have taken on a dependency that must track your vendors&#8217; IP changes, and cloud senders rotate ranges.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why hard fail is not automatically the safer choice<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">SPF records end with a qualifier on <code>all<\/code>. Soft fail is <code>~all<\/code>; hard fail is <code>-all<\/code>. The instinct is that hard fail is the stricter, more secure choice, and it is, but the DMARC specification calls out a specific cost that is easy to miss.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SPF is evaluated early in the SMTP conversation. A hard fail can get a message rejected before the message body is ever transmitted, which means before the From header is visible and before DMARC is evaluated at all. A message that would have passed DMARC on an aligned DKIM signature can be rejected purely on SPF.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Messages rejected that early never reach the DATA phase, so they never appear in your DMARC aggregate reports. You lose the failure and the evidence of the failure in the same move.<\/p><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">That is the argument for staying on <code>~all<\/code> while you are still discovering who sends as you, and moving to <code>-all<\/code> once your reports have gone quiet. On a parked domain with no legitimate senders at all, publish <code>v=spf1 -all<\/code> immediately; there is nothing to discover.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One more thing SPF does not do, and this is the root of most DMARC confusion. SPF authenticates the envelope sender, the address in the SMTP <code>MAIL FROM<\/code> command. Your recipients never see that address. They see the From header, which SPF does not check at all.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">DKIM: the signature that survives a forward<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">DKIM adds a cryptographic signature over selected headers and the message body. The public key lives in DNS under a selector, in the form <code>selector._domainkey.example.com<\/code>, and the signature header names both the selector and a signing domain in its <code>d=<\/code> tag.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short TXT s1._domainkey.example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That <code>d=<\/code> value is the part that matters and the part that gets ignored. A message can carry a perfectly valid signature from your provider&#8217;s own domain. It verifies. It proves nothing about you, because the identity it asserts is theirs. Completing your provider&#8217;s domain authentication step, the one that has you publish records under your own zone, is what moves <code>d=<\/code> onto your domain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Algorithms and key size<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The rules here are settled. Signers must use rsa-sha256. The older rsa-sha1 must not be used for signing or verifying, and signatures using it fail permanently. Keys must be at least 1024 bits and should be at least 2048. Verifiers are required to reject anything under 1024 outright.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A useful field heuristic follows from a DNS quirk. A single TXT character string maxes out around 255 characters, and a 2048-bit RSA key does not fit in one. So if your DKIM record comes back from <code>dig<\/code> as one quoted string, it is probably 1024-bit; split into two concatenated strings, probably 2048. A hint rather than proof, but it takes two seconds.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An Ed25519 signing algorithm is also defined for DKIM, with compact keys and good cryptographic properties, but support across platforms and verifiers is still uneven. RSA with SHA-256 remains the safe universal choice unless you sign with both.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rotating a key without breaking anything<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Never edit a DKIM key in place. Mail already in flight, in a queue, or sitting in a mailing list&#8217;s outbound spool was signed with the old key, and overwriting the record invalidates all of it retroactively.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Publish the new key under a new selector name and confirm it resolves.<\/li><li>Switch the signing platform to the new selector.<\/li><li>Wait out the longest plausible delivery delay, which is days rather than hours if mailing lists are involved.<\/li><li>Remove the old selector record.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">DKIM has one property SPF does not, and it decides your architecture later. A signature travels with the message. When mail passes through a forwarder, a role alias or a mailing list, the connecting IP is no longer yours and SPF fails; the DKIM signature usually still verifies. This is why the DMARC specification states that domains publishing a reject policy must not rely on SPF alone and must apply valid DKIM signatures.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">DMARC: connecting the visible domain to the proof<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">DMARC is a TXT record at <code>_dmarc.example.com<\/code>. It asks one question that neither SPF nor DKIM asks: does the domain your recipient can actually see match the domain that proved itself?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short TXT _dmarc.example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That match is called alignment. Relaxed alignment, the default, accepts any domain sharing the same organizational domain, so <code>mail.example.com<\/code> aligns with <code>example.com<\/code>. Strict requires them to be identical. A message passes DMARC if either SPF or DKIM passes <em>and<\/em> the domain that passed aligns with the From header. One aligned mechanism is enough. Both passing while neither aligns is a fail, and that is the most common cause of &#8220;but all my checkers are green.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The tags worth knowing<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li><code>p<\/code> is the policy for the domain itself: <code>none<\/code>, <code>quarantine<\/code> or <code>reject<\/code>. Omit it and the record is treated as <code>p=none<\/code>.<\/li><li><code>sp<\/code> sets a separate policy for existing subdomains.<\/li><li><code>np<\/code> sets a policy for subdomains that do not exist in DNS at all. This is the anti-spoofing tag most zones are missing.<\/li><li><code>rua<\/code> is where aggregate reports are sent. Without it you get no reports, and without reports you are guessing.<\/li><li><code>adkim<\/code> and <code>aspf<\/code> switch the two alignment modes from relaxed to strict.<\/li><li><code>t=y<\/code> is test mode. It tells receivers to apply one level below your stated policy, so a record saying reject behaves as quarantine, and quarantine behaves as none.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The DMARC specification has been rewritten and promoted onto the IETF standards track as RFC 9989, with aggregate and failure reporting split into RFC 9990 and RFC 9991, obsoleting the original RFC 7489. Existing records keep working and still begin with <code>v=DMARC1<\/code>, so nothing is urgent. Three things are worth acting on at your next zone edit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>pct<\/code>, <code>rf<\/code> and <code>ri<\/code> tags are gone. Unknown tags are ignored rather than treated as errors, so leaving them does no damage, but <code>pct<\/code> no longer means anything and the staged rollout it was used for is now <code>t=y<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Public Suffix List is no longer how receivers determine your organizational domain. They now walk up the DNS hierarchy looking for a DMARC record at each level, capped at eight queries. For a two-label domain this changes nothing. For a deep subdomain hierarchy it can resolve differently than the old method did, and a name deeper than eight labels will never have its policy record found by the walk. If you run a complex namespace, publish an explicit record at the exact name rather than relying on inheritance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And if two DMARC TXT records are returned for the same name, both are discarded. A duplicate is not a merge or a tiebreak. It is the same as having none.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Reading the reports<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Aggregate reports arrive as gzipped XML, typically once a day per reporting provider. They are technically human-readable and practically not, especially once a dozen providers are reporting on a domain with several sending services.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two honest choices. Parse them yourself, which is a small satisfying project that gives you exactly the view you want. Or point <code>rua<\/code> at a hosted processor; Dmarcian, Valimail and PowerDMARC all do this competently, with entry tiers sufficient for one domain. The trade is that you are sending metadata about your mail flows to a third party and inheriting their retention terms. Read those terms first in a regulated environment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Domain architecture: the decision that stops this recurring<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Everything above is records. This part is structure, and it is what separates a zone that stays correct from one that quietly rots.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Put each sending stream on its own subdomain. People mail from the apex. Marketing sends from something like <code>news.example.com<\/code>. Transactional and application mail sends from <code>mail.example.com<\/code> or similar. Each subdomain gets its own SPF record, its own DKIM selectors, and its own DMARC record if you want a different policy there.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Each subdomain gets a fresh ten-lookup SPF budget, which is usually what forced the decision in the first place.<\/li><li>A marketing platform that gets breached or blocklisted does not drag your invoices and password resets down with it.<\/li><li>Reputation is scoped. Bulk sending and one-to-one business mail get judged separately, which is what you want, because they behave nothing alike.<\/li><li>You can hold the apex at a strict policy while a subdomain is still being brought into line.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The cost is more records to maintain and one more thing to explain to whoever inherits the zone. It is worth it the first time a vendor migration happens and you only have to touch one subdomain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then close the gaps. Every domain that never sends and never receives should carry a null MX, an SPF record of <code>v=spf1 -all<\/code>, and DMARC at <code>p=reject<\/code>. Three records, five minutes, and the domain leaves the pool of things abusable in your name. Add <code>np=reject<\/code> on live domains too, because an attacker does not need a subdomain to exist in order to put it in a From header.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rolling it out without losing mail<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The order matters, because each step depends on evidence produced by the one before it.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>Inventory every sender.<\/strong> Mailbox provider, CRM, helpdesk, billing system, marketing platform, monitoring alerts, and the tool a department signed up for without telling anyone. This list is always longer than expected and it is the highest-value step here.<\/li><li><strong>Fix MX first,<\/strong> with a low TTL if you are migrating. Inbound is what people notice within minutes.<\/li><li><strong>Publish SPF within budget,<\/strong> ending in <code>~all<\/code> for now. Count lookups before publishing, not after mail fails.<\/li><li><strong>Get DKIM signing on your own domain<\/strong> for every stream. Verify <code>d=<\/code> in the headers of a real received message rather than trusting a dashboard.<\/li><li><strong>Publish DMARC at <code>p=none<\/code> with a <code>rua<\/code> address.<\/strong> This changes nothing about delivery and starts the flow of evidence.<\/li><li><strong>Read reports for several weeks.<\/strong> Longer if you have quarterly patterns like invoicing runs or annual renewals, which is exactly the mail you cannot afford to break.<\/li><li><strong>Move to <code>p=quarantine<\/code><\/strong> once every remaining failure is one you recognize as spoofing. Use <code>t=y<\/code> for a softer first step.<\/li><li><strong>Move to <code>p=reject<\/code>,<\/strong> confirming DKIM is aligned on every stream first, then tighten SPF to <code>-all<\/code>.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Step six is the one people compress, and it is the only step that generates the information the last two depend on. Skipping it means going to enforcement blind and finding out which stream you broke from a colleague rather than from a report.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Steps one and six are also the two that never finish. Keep the sender inventory current as vendors come and go, and keep reading reports after you reach enforcement, because a new tool bought by a department you never talk to shows up in a report long before it shows up in a conversation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting, in the order worth checking<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When something is wrong, the first question is which of the two jobs failed. Inbound problems and spoofing problems share no diagnostic steps.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inbound mail is not arriving<\/h3>\n\n\n\n<ol class=\"wp-block-list\"><li>Confirm the MX records exist and resolve, and that each target has an A or AAAA record.<\/li><li>Query your authoritative nameservers directly rather than a resolver, so you are looking at what you published rather than what is cached.<\/li><li>Confirm the mail host actually answers on port 25 and offers STARTTLS.<\/li><li>If all three pass, the problem is inside the mail platform: routing rules, a filter, an aliasing mistake, a mailbox over quota. It is no longer DNS.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short NS example.com\ndig @ns1.example-dns.net example.com MX\nopenssl s_client -starttls smtp -connect mail.example.com:25<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Legitimate mail is being rejected or quarantined<\/h3>\n\n\n\n<ol class=\"wp-block-list\"><li>Read the SMTP rejection text. Receivers name the reason, and DMARC-related rejections usually say so in plain words.<\/li><li>Open the headers of a message that failed and read the authentication results. They tell you which check failed and which domain was evaluated.<\/li><li>Compare the <code>d=<\/code> value in the DKIM signature against the From domain. If they differ and share no organizational domain, alignment is your problem.<\/li><li>Count your SPF lookups. A permanent error there presents as a plain SPF failure with nothing in the record that looks wrong.<\/li><li>Check the sending IP has a valid reverse DNS record that resolves forward again. Only whoever controls the IP can set this, which means your provider if you are on shared infrastructure, or you if you run your own server.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>dig -x 203.0.113.10 +short<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That reverse DNS point matters more than it looks. Major mailbox providers expect sending IPs to have valid forward and reverse DNS, so if you run your own mail server, PTR control is a hard requirement rather than a nice-to-have. Confirm it before you buy. Hosts aimed at self-hosting, InterServer and Contabo among them, expose PTR in the panel; plenty of budget instances do not, and some block port 25 outright.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common mistakes<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Treating <code>p=none<\/code> as done.<\/strong> It is a monitoring mode. It provides no protection whatsoever, and every checker will still show you a green tick.<\/li><li><strong>Publishing two SPF records.<\/strong> Usually one from the mailbox provider&#8217;s setup wizard and one from a marketing tool. The result is worse than either alone.<\/li><li><strong>Assuming a passing DKIM signature is your DKIM signature.<\/strong> Check <code>d=<\/code>, not the presence of a signature.<\/li><li><strong>Editing a DKIM key in place<\/strong> instead of rotating through a second selector.<\/li><li><strong>Leaving parked and brand domains bare.<\/strong> No MX, no SPF, no DMARC is an open invitation, and these domains are usually the ones nobody is monitoring.<\/li><li><strong>Going to <code>p=reject<\/code> without DKIM aligned<\/strong> on every stream. Forwarded mail will break, and forwarded mail is disproportionately mail from customers.<\/li><li><strong>Setting <code>rua<\/code> and never reading it.<\/strong> Reports you do not process are the same as reports you never requested.<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently asked questions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need both SPF and DKIM, or is one enough?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">DMARC only needs one of them to pass and align. Publish both anyway. They fail in different circumstances, and having only one means any situation that breaks it breaks all your authentication at once. Major mailbox providers also expect both from higher-volume senders, and DKIM specifically is required if you intend to publish a reject policy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How long should I stay at p=none?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Long enough to see a full cycle of your sending patterns, plus time to fix what the reports reveal. For a small business with a mailbox provider and two SaaS tools, a few weeks. For an organization with quarterly billing runs and departments who buy their own software, months. The signal to move is that you recognize every remaining failure as illegitimate, not that a calendar reminder fired.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Will DMARC stop phishing?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It stops exact-domain spoofing, one technique among several. It does nothing about lookalike domains, nothing about display-name spoofing where the visible name says your CEO but the address is free webmail, and nothing about a compromised mailbox sending properly authenticated mail. One control worth having, not a phishing solution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does any of this affect whether I receive email?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. SPF, DKIM and DMARC describe mail leaving your domain. Only MX affects mail arriving at it. The one indirect connection is that your own inbound filtering may evaluate other people&#8217;s SPF and DKIM when deciding what to do with their mail, but that is your mail platform&#8217;s behavior, not your DNS records.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need to update my records for the new DMARC RFCs?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nothing breaks if you do nothing. At your next edit, drop <code>pct<\/code>, <code>rf<\/code> and <code>ri<\/code> if they are present, consider adding <code>np<\/code> to close the non-existent subdomain gap, and if you run a deep subdomain hierarchy, publish explicit records rather than relying on inheritance. Leave the rest at defaults, because the defaults are sensible.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">My mail goes to spam even though everything passes. What now?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Authentication and reputation are different problems. Passing DMARC tells a receiver the mail genuinely came from you; it says nothing about whether recipients want it. If authentication is clean, look at complaint rates, list hygiene, volume ramps and content. Google publishes a spam complaint ceiling and its guidance is to operate well below that ceiling, not near it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping up<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you take one thing from this, take the distinction between publishing and enforcing. Business email DNS gives you four records that answer four different questions, and only one of them, the DMARC policy tag, actually instructs a receiving server to do anything. Every free checker will confirm the records exist. None of them will tell you the dial is at zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Get MX right so mail arrives. Keep SPF inside its lookup budget. Make DKIM sign with your own domain so <code>d=<\/code> aligns. Publish DMARC at <code>p=none<\/code> with a reporting address, read what comes back for as long as it takes, then move the dial until it reaches reject.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And while you are in the zone, spend five minutes on the domains nobody thinks about. A null MX, an empty SPF record and a reject policy on a parked domain is the cheapest security work available to you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Need a second pair of eyes on your mail domain?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mail DNS is unusually well suited to outside help, because the failure is almost always somewhere the domain owner cannot see it: in a header, in a report nobody parses, or in a vendor&#8217;s include chain. Things I regularly help with:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Auditing an existing zone across MX, SPF, DKIM and DMARC and telling you plainly what is exposed and what is fine<\/li><li>Getting an SPF record back under the ten-lookup limit without breaking a sender you forgot about<\/li><li>Planning and executing the move from <code>p=none<\/code> to <code>p=quarantine<\/code> to <code>p=reject<\/code>, including the sender inventory and the report reading<\/li><li>Setting up DMARC aggregate report collection and parsing, either self-hosted or on a processor<\/li><li>Splitting sending streams onto subdomains and migrating each one without a delivery gap<\/li><li>Locking down parked and brand-protection domains so they stop being usable in your name<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you would rather not describe the problem in the abstract, send me the output of a <code>dig<\/code> against your domain, or a set of headers from a message that failed, and I will tell you what I see in it.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.upwork.com\/freelancers\/~01f15a912ad84a6620\" target=\"_blank\" rel=\"noreferrer noopener\">Work with me on Upwork<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Your domain has all four records. Every free checker shows green. It is still trivially spoofable, because publishing a record and enforcing a policy are different acts. A working guide to business email DNS: what MX, SPF, DKIM and DMARC each actually protect, the SPF lookup budget and the void-lookup limit nobody watches, why DKIM alignment decides whether you can ever reach p=reject, the domain architecture that stops the problem recurring, and a rollout order that gets you to enforcement without losing legitimate mail.<\/p>\n","protected":false},"author":1,"featured_media":439,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,52,30],"tags":[617,618,65,276,277,619,68,66,73,280,279,74,616,278,75,78,112],"class_list":["post-438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-networking","category-technical-guides","category-web-security","tag-anti-spoofing","tag-business-email","tag-dig","tag-dkim","tag-dmarc","tag-dmarc-reporting","tag-dns","tag-dns-records","tag-domain-configuration","tag-email-authentication","tag-email-deliverability","tag-mx-records","tag-null-mx","tag-smtp","tag-spf","tag-ttl","tag-web-security","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Business Email DNS: MX, SPF, DKIM and DMARC Done Right<\/title>\n<meta name=\"description\" content=\"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Business Email DNS: MX, SPF, DKIM and DMARC Done Right\" \/>\n<meta property=\"og:description\" content=\"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/\" \/>\n<meta property=\"og:site_name\" content=\"John Nessime\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-23T09:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-14T13:13:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"627\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"John Nessime\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"John Nessime\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/\"},\"author\":{\"name\":\"John Nessime\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"headline\":\"Business Email DNS Done Right: MX, SPF, DKIM and DMARC\",\"datePublished\":\"2026-08-23T09:00:00+00:00\",\"dateModified\":\"2026-09-14T13:13:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/\"},\"wordCount\":3994,\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/business-email-dns-mx-spf-dkim-dmarc-featured.png\",\"keywords\":[\"Anti-Spoofing\",\"Business Email\",\"dig\",\"DKIM\",\"DMARC\",\"DMARC Reporting\",\"DNS\",\"DNS Records\",\"Domain Configuration\",\"Email Authentication\",\"Email Deliverability\",\"MX Records\",\"Null MX\",\"SMTP\",\"SPF\",\"TTL\",\"Web Security\"],\"articleSection\":[\"Networking\",\"Technical Guides\",\"Web Security\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/\",\"name\":\"Business Email DNS: MX, SPF, DKIM and DMARC Done Right\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/business-email-dns-mx-spf-dkim-dmarc-featured.png\",\"datePublished\":\"2026-08-23T09:00:00+00:00\",\"dateModified\":\"2026-09-14T13:13:09+00:00\",\"description\":\"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#primaryimage\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/business-email-dns-mx-spf-dkim-dmarc-featured.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/business-email-dns-mx-spf-dkim-dmarc-featured.png\",\"width\":1200,\"height\":627,\"caption\":\"Dark technical diagram titled Business Email DNS. Four pill-shaped badges across the top read MX, SPF, DKIM and DMARC, each with a green dot, labelled published and four records, four green ticks. Below, an enforcement slider runs from p=none through p=quarantine to p=reject, with a glowing amber handle parked at p=none marked you are here, and a red caption reading domain still spoofable. Footer badges note the SPF budget of ten lookups and two void lookups, DKIM d= must align with From, and DMARC p= as the only enforcement dial.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/technical-guides\\\/business-email-dns-mx-spf-dkim-dmarc\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Business Email DNS Done Right: MX, SPF, DKIM and DMARC\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\",\"name\":\"John Nessime\",\"description\":\"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained\",\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\",\"name\":\"John Nessime\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"width\":512,\"height\":512,\"caption\":\"John Nessime\"},\"logo\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\"},\"description\":\"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.\",\"sameAs\":[\"https:\\\/\\\/john-nessime.com\\\/blog\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/john-m-nessime\"],\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/author\\\/johnnessime\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Business Email DNS: MX, SPF, DKIM and DMARC Done Right","description":"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/","og_locale":"en_US","og_type":"article","og_title":"Business Email DNS: MX, SPF, DKIM and DMARC Done Right","og_description":"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.","og_url":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/","og_site_name":"John Nessime","article_published_time":"2026-08-23T09:00:00+00:00","article_modified_time":"2026-09-14T13:13:09+00:00","og_image":[{"width":1200,"height":627,"url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png","type":"image\/png"}],"author":"John Nessime","twitter_card":"summary_large_image","twitter_misc":{"Written by":"John Nessime","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#article","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/"},"author":{"name":"John Nessime","@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"headline":"Business Email DNS Done Right: MX, SPF, DKIM and DMARC","datePublished":"2026-08-23T09:00:00+00:00","dateModified":"2026-09-14T13:13:09+00:00","mainEntityOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/"},"wordCount":3994,"publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png","keywords":["Anti-Spoofing","Business Email","dig","DKIM","DMARC","DMARC Reporting","DNS","DNS Records","Domain Configuration","Email Authentication","Email Deliverability","MX Records","Null MX","SMTP","SPF","TTL","Web Security"],"articleSection":["Networking","Technical Guides","Web Security"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/","url":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/","name":"Business Email DNS: MX, SPF, DKIM and DMARC Done Right","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#primaryimage"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png","datePublished":"2026-08-23T09:00:00+00:00","dateModified":"2026-09-14T13:13:09+00:00","description":"Business email DNS explained: what MX, SPF, DKIM and DMARC each protect, the failure modes that stay invisible, and how to reach p=reject safely.","breadcrumb":{"@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#primaryimage","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/business-email-dns-mx-spf-dkim-dmarc-featured.png","width":1200,"height":627,"caption":"Dark technical diagram titled Business Email DNS. Four pill-shaped badges across the top read MX, SPF, DKIM and DMARC, each with a green dot, labelled published and four records, four green ticks. Below, an enforcement slider runs from p=none through p=quarantine to p=reject, with a glowing amber handle parked at p=none marked you are here, and a red caption reading domain still spoofable. Footer badges note the SPF budget of ten lookups and two void lookups, DKIM d= must align with From, and DMARC p= as the only enforcement dial."},{"@type":"BreadcrumbList","@id":"https:\/\/john-nessime.com\/blog\/technical-guides\/business-email-dns-mx-spf-dkim-dmarc\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/john-nessime.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Business Email DNS Done Right: MX, SPF, DKIM and DMARC"}]},{"@type":"WebSite","@id":"https:\/\/john-nessime.com\/blog\/#website","url":"https:\/\/john-nessime.com\/blog\/","name":"John Nessime","description":"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained","publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/john-nessime.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105","name":"John Nessime","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","width":512,"height":512,"caption":"John Nessime"},"logo":{"@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png"},"description":"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.","sameAs":["https:\/\/john-nessime.com\/blog","https:\/\/www.linkedin.com\/in\/john-m-nessime"],"url":"https:\/\/john-nessime.com\/blog\/author\/johnnessime\/"}]}},"_links":{"self":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/comments?post=438"}],"version-history":[{"count":1,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/438\/revisions"}],"predecessor-version":[{"id":488,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/438\/revisions\/488"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media\/439"}],"wp:attachment":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media?parent=438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/categories?post=438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/tags?post=438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}