Why Gmail Isn’t Showing the Unsubscribe Button (and How to Fix It)

Gmail shows its native unsubscribe button only when a message passes Google’s automated eligibility checks, and a List-Unsubscribe header is just one of those checks, not a guarantee. Per Google’s own sender guidelines FAQ, “unsubscribe buttons or links are displayed at the top of messages (next to the sender name) only for messages that pass Google’s automated eligibility checks,” which cover header syntax, a DKIM signature that protects those headers, and sender-level factors like spam rate and sending volume. So if the headers look right in the source and the button still isn’t there, the cause is usually one of the checks below, not the syntax. This is a diagnostic checklist, not an explainer: for the mechanics, see how the List-Unsubscribe header works first.

The Diagnostic Checklist: Cheapest Checks First

Work through these in order. The first five are header checks you can confirm in a minute from the raw message; the later ones take longer to diagnose.

1. One of the two headers is missing

Symptom: No unsubscribe button in Gmail or in any other client that supports List-Unsubscribe.

How to confirm: Open “Show original” in Gmail (see below) and search the raw headers for List-Unsubscribe and List-Unsubscribe-Post. One-click needs both: the URL header, and the header that flags it as one-click.

Fix: Add both. RFC 2369 defines List-Unsubscribe; RFC 8058 defines List-Unsubscribe-Post. Marketing platforms usually add these automatically (see the platform table below); transactional and self-hosted sends usually require you to set them yourself.

2. You only have a mailto: link, no https URL

Symptom: The header is present, but one-click unsubscribe doesn’t work in Gmail. Gmail may still offer a mailto-based unsubscribe, but that doesn’t meet its bulk-sender requirement.

How to confirm: Check the List-Unsubscribe value. If it only contains <mailto:[email protected]> with no https:// URL, that’s the problem. Google’s FAQ is direct about it: “We’ll continue to support mailto links but they don’t meet our one-click unsubscribe requirement.”

Fix: RFC 8058 states the header field “MUST contain one HTTPS URI,” and may also include a mailto URI. Include both: https enables one-click, and mailto covers older clients like iOS Mail and Outlook.com, which only support that method.

3. The header syntax is malformed

Symptom: The header exists but Gmail doesn’t treat it as one-click.

How to confirm: Check against the RFC 2369 syntax: values wrapped in angle brackets, multiple URIs comma-separated. List-Unsubscribe: https://example.com/unsub (no brackets) breaks the syntax. <http://example.com/unsub> is valid under RFC 2369 but fails RFC 8058, which requires an HTTPS URI for one-click.

Fix: Use List-Unsubscribe: <https://example.com/unsubscribe?id=123>, <mailto:[email protected]>. Verify it with the curl command later in this post before trusting it in production.

4. Your DKIM signature doesn’t cover the unsubscribe headers

Symptom: Headers look correct, DKIM passes, but the button still doesn’t appear.

How to confirm: In the raw message, find the DKIM-Signature header and check its h= tag, the list of headers the signature covers. If list-unsubscribe and list-unsubscribe-post aren’t in that list, the signature doesn’t protect them.

Fix: RFC 8058 is explicit: “The List-Unsubscribe and List-Unsubscribe-Post headers MUST be covered by the signature and included in the ‘h=’ tag of a valid DKIM-Signature header field.” This stops tampering with the unsubscribe URL after signing. Most DKIM signature header lists are set once at the server or ESP level, so it’s usually an infrastructure fix, not a per-message one.

5. DKIM fails, or isn’t aligned with your From domain

Symptom: The button appears sometimes and not others, or never for a specific sending domain.

How to confirm: Check Gmail’s “Authentication-Results” header for dkim=pass and confirm the signing domain matches your From domain (or its organizational domain). Gmail shows it as header.i=@yourdomain there; the same domain appears as the d= tag in the DKIM-Signature header.

Fix: Per Google’s sender guidelines, “the domain in the sender’s From: header must be aligned with either the SPF domain or the DKIM domain.” A mismatched or failing signature undermines the trust signal the button depends on.

6. Your sending reputation is too new or too weak

Symptom: Headers and DKIM are both correct, but the button is inconsistent or absent, especially for newer domains or low volume.

How to confirm: No header to check here. Google’s FAQ ties eligibility to sender requirements “including increasing sending volumes gradually and monitoring recipients’ spam reports,” and SendGrid’s docs agree: “Low sender reputations can occasionally cause the one click unsubscribe button to not be displayed.”

Fix: Warm up new sending domains gradually, keep spam complaint rates low, and monitor sender reputation in Google Postmaster Tools. There’s no header fix for a reputation problem.

7. Gmail doesn’t treat the message as a subscription message

Symptom: One-off or personal-looking emails (receipts, password resets, one-to-one sends) don’t show the button, even with correct headers.

How to confirm: Ask whether the message is genuinely bulk or promotional. Google’s FAQ states that “one-click unsubscribe is required only for marketing and promotional messages. Transactional messages are excluded from this requirement,” and gives password reset messages, reservation confirmations, and form submission confirmations as examples.

Fix: This isn’t a bug, it’s a scope question. If the send in question is genuinely transactional vs marketing email, one-click unsubscribe was never expected to appear on it.

8. Your unsubscribe endpoint itself is broken

Symptom: The button appears, but clicking it doesn’t remove the recipient.

How to confirm: Test the endpoint directly with curl (see below). Look for a non-2xx response, a redirect, a login wall, or a confirmation page.

Fix: RFC 8058 says “the mail sender MUST NOT return an HTTPS redirect,” and that the POST request “MUST NOT include cookies, HTTP authorization, or any other context information.” In practice, the endpoint must unsubscribe the recipient from the URL alone, with no session, login, or confirmation step. Google also recommends honoring requests within 48 hours, and Yahoo within two days.

9. The button appears inconsistently

Symptom: Some recipients see it and some don’t, or it shows on some of your messages but not others.

How to confirm: Usually there’s no single header to point to. It’s typically the reputation and classification issues above, applied per-message or per-recipient rather than per-domain.

Fix: Rule out headers, DKIM, and syntax first, then treat it as a reputation and volume issue rather than a one-time configuration bug.

One more thing the checklist above doesn’t cover: none of this replaces the unsubscribe link in the email body. Google’s guidelines require both, a one-click header and a visible link in the message itself, regardless of which mailbox providers render the button.

How to Inspect the Headers Yourself in Gmail

Open the message, click the three-dot menu, and select “Show original.” Search the raw source for these lines:

List-Unsubscribe: <https://example.com/unsubscribe?id=abc123>, <mailto:[email protected]>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector1;
  h=from:to:subject:date:message-id:list-unsubscribe:list-unsubscribe-post;
  bh=...; b=...
Authentication-Results: mx.google.com;
  dkim=pass [email protected] header.s=selector1 header.b=...;
  spf=pass ...

Confirm three things: both headers are present and correctly formatted, list-unsubscribe and list-unsubscribe-post appear in the DKIM h= list, and Authentication-Results shows dkim=pass aligned to your From domain.

How to Test Your One-Click Endpoint With curl

Before trusting an endpoint in production, send it the same request Gmail would:

curl -i -X POST "https://example.com/unsubscribe?id=abc123" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data "List-Unsubscribe=One-Click"

A compliant endpoint returns a 2xx status with no Location header and no login prompt. A 3xx, a 4xx, or a confirmation page is the exact failure RFC 8058 was written to prevent, and it’s also a fast route to emails landing in spam once frustrated recipients hit “report spam” instead.

How List-Unsubscribe Support Differs Across Email Platforms

Every cell comes from that vendor’s own documentation, linked in the row. Where the docs don’t state something clearly, the cell says “Not documented” rather than guessing.

PlatformAdds headers automatically?One-click (RFC 8058) supported?Who hosts the unsubscribe endpoint
MailchimpMarketing campaigns: not documented. Transactional (API): yes, with the built-in unsubscribe link; you can supply your own header insteadNot documentedMailchimp, for the built-in transactional link
KlaviyoYes, automatically, “to enable one-click unsubscribes for supported inboxes”Yes, stated as meeting the Google/Yahoo requirementNot documented
BrevoYes, on marketing and transactional sends alikeStated as already compliant with the Gmail/Yahoo mandateNot documented
HubSpotNot documented in HubSpot’s own knowledge baseNot documentedNot documented
Customer.ioYes, only on the built-in unsubscribe feature; custom flows must implement it themselvesYes, for the default flow; self-managed for custom flowsCustomer.io by default; the sender for custom flows
Amazon SESOnly if you opt in to subscription management (ListManagementOptions) with Easy DKIM; otherwise you set headers yourselfYes, via List-Unsubscribe-Post: List-Unsubscribe=One-ClickSES-hosted under subscription management; self-hosted otherwise
SendGridYes, if Subscription Tracking is enabled; otherwise manual via API/SMTP headersYes, inserted with Subscription Tracking or set manuallySendGrid-hosted with Subscription Tracking; a URL you specify otherwise
MailgunYes, once enabled at the domain or API levelYes, fully supportedMailgun hosts and auto-processes the requests
PostmarkYes, by default on the Broadcast stream; manual on TransactionalYes, for Broadcast; sender-managed for TransactionalPostmark for Broadcast; the sender for Transactional
ResendNo, for transactional sends via /emails: you add the header via the headers parameterSender-implemented: you set the header and handle the POSTThe sender’s own server

The pattern across every documented row: marketing platforms that also host your mailing list tend to add the headers for you. Transactional email APIs more often put the header and the endpoint in your hands, since they send on your behalf without owning your subscriber data. That handoff is where most “button not showing” reports start: the marketing product works out of the box, but a transactional stream from the same vendor doesn’t inherit that behavior automatically.

Frequently Asked Questions

Why does Gmail show the unsubscribe button for some senders and not others?

Gmail only displays it for messages that pass its automated eligibility checks: correct headers, a DKIM signature covering them, DMARC alignment, and sender-level factors like spam complaint rate and volume. Two senders with identical headers can get different results if their reputations differ.

Does adding a List-Unsubscribe header guarantee the button will appear?

No. Google’s own guidance states the button appears “only for messages that pass Google’s automated eligibility checks,” and specifically notes this holds “even when senders add their own unsubscribe link to the message body.” The header is necessary but not sufficient.

How long does it take for the button to appear after I fix the headers?

Google doesn’t publish a delay. Header fixes apply to new messages, not ones already delivered, so check a fresh send. If the button still doesn’t appear there, recheck DKIM coverage and sending reputation rather than waiting longer.

Do I need a List-Unsubscribe header on transactional email?

No. Google excludes transactional messages, such as password resets and reservation or form confirmations, from the one-click requirement. Adding the header to transactional mail isn’t required, though it isn’t harmful if the message is genuinely one-to-one.

Do Outlook, Apple Mail, and Yahoo Mail work the same way as Gmail?

Not identically. Per Brevo’s own documentation, Outlook.com and Apple’s iOS Mail currently support only the mailto method, not one-click https. Yahoo Mail does support one-click like Gmail, and its Sender Hub recommends the RFC 8058 POST method while still accepting mailto.

Is a mailto-only List-Unsubscribe header still valid?

It’s valid under RFC 2369, and some clients (Outlook.com, iOS Mail) only support mailto. But RFC 8058 requires an https URI for one-click, and Google says mailto links “don’t meet our one-click unsubscribe requirement.” Include both to cover the widest range of clients.

Can I test my one-click endpoint before sending to real subscribers?

Yes. Send the endpoint a POST request with Content-Type: application/x-www-form-urlencoded and a body of List-Unsubscribe=One-Click, using curl or a similar tool, and confirm it returns a 2xx status with no redirect and no login prompt. This is the same request Gmail and Yahoo send when a recipient clicks one-click unsubscribe.