Suped

Why does Gmail List-Unsubscribe only work on the second attempt?

Michael Ko profile picture
Michael Ko
Co-founder & CEO, Suped
Published 3 May 2025
Updated 25 May 2026
9 min read
Summarize with
Gmail List-Unsubscribe second attempt explained with a POST endpoint visual.
Gmail List-Unsubscribe usually works on the second attempt because the first attempt is the one-click POST request, and the sender's unsubscribe endpoint rejects or blocks POST. Gmail then falls back to a web-style flow on the next attempt, often showing "Go to Website" instead of "Unsubscribe". That second path reaches the URL with a GET request or sends the user to the preference page, so it looks like Gmail only works on retry.
The fix is direct: make the HTTPS URL in the List-Unsubscribe header accept POST, process List-Unsubscribe=One-Click without a login or confirmation page, and return a clean 200-class response. If your endpoint only supports GET, Gmail's first one-click action fails even though your visible unsubscribe page still works.
When I troubleshoot this, I start with the raw headers and server logs. The UI popup is useful, but the answer is usually in the HTTP method, response code, redirects, and authentication state of the unsubscribe URL.

The short answer

Most likely cause
Your one-click unsubscribe URL is not accepting POST. Gmail sees List-Unsubscribe-Post, tries the one-click POST path first, gets a blocked request or bad response, then uses a different web flow on the second attempt.
  1. First attempt: Gmail attempts the one-click unsubscribe action with POST.
  2. Failure point: The sender endpoint blocks POST, requires a token in a browser session, redirects badly, or returns a non-success status.
  3. Second attempt: Gmail shows a different popup and sends the recipient through the website path.
  4. Correct fix: Make the unsubscribe URL accept an unauthenticated HTTPS POST and unsubscribe the recipient from that mailing stream.
This is not mainly a Gmail button problem. It is an implementation mismatch between the headers that advertise one-click unsubscribe and the endpoint that receives Gmail's request. If you publish List-Unsubscribe-Post: List-Unsubscribe=One-Click, the HTTPS URL needs to behave like a one-click receiver, not only like a normal web page.
I also check whether the sender has consistent authentication. Gmail's in-app unsubscribe UI is affected by trust signals as well as header syntax. Passing SPF, DKIM, DMARC, and keeping complaints down helps Gmail decide whether to display and use the unsubscribe affordance at all. Suped's DMARC monitoring helps connect those authentication signals to the sending sources that created them.
Gmail unsubscribe popup with a second website fallback state.
Gmail unsubscribe popup with a second website fallback state.

What Gmail is doing

There are two different unsubscribe experiences that get mixed together. The first is one-click unsubscribe, where Gmail can send a POST request to the URL in the header after the user confirms. The second is the website unsubscribe flow, where Gmail gives the recipient a way to open the sender's unsubscribe or preference page.
If the POST path fails, the user sees a confusing result. The button can remain visible because Gmail did not complete the one-click action. When the user tries again, Gmail can present a different popup that sends them to the web page. The URL then appears to work, but that success came through a different method.
One-click path
  1. Method: Gmail sends an HTTPS POST to the List-Unsubscribe URL.
  2. User step: The recipient confirms inside Gmail and does not complete another form.
  3. Endpoint role: The server unsubscribes the recipient from the mailing stream.
  4. Success sign: Server logs show POST with a 200-class response.
Website path
  1. Method: The browser opens the URL with a normal page request.
  2. User step: The recipient lands on a page, preference center, or confirmation screen.
  3. Endpoint role: The server displays a web experience and then processes the unsubscribe.
  4. Success sign: The page opens and the recipient can complete the request.
The practical lesson is simple: do not use a web-page-only endpoint for one-click unsubscribe. The same URL can support both methods, but the POST branch needs to unsubscribe immediately and the GET branch can show the page.

The header pattern I would use

I prefer to keep the header order close to common examples: List-Unsubscribe first, then List-Unsubscribe-Post. Header order should not be the main semantic factor, but real parsers are not always forgiving. I remove ambiguity where I can.
Recommended List-Unsubscribe headerstext
List-Unsubscribe: <https://example.com/u/abc123>, <mailto:unsubscribe@example.com?subject=unsubscribe> List-Unsubscribe-Post: List-Unsubscribe=One-Click
The HTTPS URL should be the real one-click endpoint, not a general account settings page. The mailto address is still a useful compatibility fallback for clients that use email-based unsubscribe handling, but Gmail's one-click behavior depends on the HTTPS POST path.
A header pattern that causes second-attempt symptomstext
List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: <https://example.com/unsubscribe.html?opaque=123456>
That second example is not automatically broken because of order alone. The real problem appears when the URL accepts a browser GET but rejects the POST that Gmail sends for one-click. If both headers exist, treat POST support as mandatory.
Flowchart showing Gmail POST first and website fallback after a failed endpoint.
Flowchart showing Gmail POST first and website fallback after a failed endpoint.

How to build the endpoint

The endpoint should treat the opaque token in the URL as enough context to identify the recipient and mailing stream. It should not require a logged-in session, a browser cookie, a CAPTCHA, or a second confirmation step for the POST request. Those controls belong on the GET page, not on the one-click action.
  1. Accept POST: Allow POST at the exact HTTPS URL published in the header.
  2. Read the body: Accept List-Unsubscribe=One-Click as the form body when present.
  3. Use tokens: Map the opaque URL token to the subscriber and list without exposing personal data.
  4. Return success: Send a 200-class response once the unsubscribe is accepted.
  5. Handle repeats: Make duplicate requests idempotent so retries do not create errors.
POST test for the unsubscribe endpointbash
curl -i -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ --data "List-Unsubscribe=One-Click" \ "https://example.com/u/abc123"
A good response is boring: 200, 202, or another success status with no forced browser path. A 403, 405, 429, web application firewall block, bot challenge, or redirect to a login page explains the second-attempt behavior.

Check

Pass condition

Failure sign

Method
POST allowed
405 status
Auth
No login
Redirect
Security
No challenge
403 status
Token
Valid opaque ID
Unknown user
Repeat
Same success
Second error
Endpoint checks that explain Gmail retry behavior

What to test before blaming Gmail

I would test the actual received message, not the template in the sending platform. Header folding, link rewriting, tracking domains, and final rendered headers can change between template design and inbox delivery. Send a real message to a Gmail account, inspect the raw source, then compare the URL in the header with the URL that receives traffic in your server logs.
Use Suped's email tester to send a live message, review authentication, and catch header or DNS issues in the same workflow. This is useful when the unsubscribe issue sits beside SPF, DKIM, or DMARC failures that make Gmail less willing to show its native unsubscribe UI.

Email tester

Send a real email to this address. Suped opens the report when the test is ready.

?/43tests passed
Preparing test address...
After that, use a domain-level pass to confirm the authentication baseline. Suped's domain health checker checks DMARC, SPF, and DKIM together, which saves time when the Gmail UI is inconsistent across campaigns or subdomains.
  1. Raw header: Confirm the delivered message contains both List-Unsubscribe and List-Unsubscribe-Post.
  2. Server logs: Look for Gmail's POST request at the exact URL in the received header.
  3. Response code: Record the status, redirect chain, and body handling for the POST attempt.
  4. Authentication: Verify DKIM passes and DMARC passes for the visible sending domain.
  5. Reputation: Check whether the sender and link domains have enough trust for Gmail to display the native UI.
For deeper implementation detail, I would compare the endpoint with GET versus POST handling and the current one-click unsubscribe requirements. Those two checks separate protocol errors from mailbox-provider eligibility issues.

Gmail display rules still matter

A working POST endpoint fixes the second-attempt symptom, but it does not guarantee that Gmail always shows the unsubscribe button beside the sender. Gmail also evaluates sender behavior, authentication, and link trust. A sender with weak authentication or poor complaint history can have correct headers and still see inconsistent UI.
Troubleshooting priority
A practical order for deciding where to spend time when Gmail unsubscribe behavior is inconsistent.
Fix first
Endpoint
POST blocked, 405 response, login redirect, bot challenge, or token failure.
Check next
Headers
Missing or malformed List-Unsubscribe headers in the delivered message.
Confirm after
Trust
SPF, DKIM, DMARC, complaint rates, and link-domain reputation.
Keep stable
Operations
Idempotent unsubscribe handling and clean list suppression.
Suped is useful here because the investigation rarely stays inside one header. A domain can have a valid unsubscribe endpoint and still have a DKIM source failing, an SPF record near lookup limits, or a sending subdomain with no DMARC policy. Suped brings those signals into one operational view with automated issue detection, real-time alerts, hosted DMARC, hosted SPF, SPF flattening, hosted MTA-STS, blocklist monitoring, and multi-tenant reporting for teams that manage many domains.
Issue steps to fix dialog showing the issue overview, tailored fix steps, and verification action
Issue steps to fix dialog showing the issue overview, tailored fix steps, and verification action
That matters because the fix needs to be verifiable. I want to see the POST succeed, then see authentication remain stable for the traffic source that sends the message. Otherwise, the unsubscribe fix works in isolation but the Gmail UI remains inconsistent.

A complete fix checklist

If I had to reduce this to a production checklist, I would make the endpoint method-safe, keep the headers predictable, and verify the delivered message against Gmail itself.
Production checklist
  1. POST support: Allow POST on the exact HTTPS URL in the delivered header.
  2. One-click body: Accept List-Unsubscribe=One-Click and do not require extra user action.
  3. GET page: Keep GET available for the visible website or preference-center flow.
  4. Header order: Publish List-Unsubscribe before List-Unsubscribe-Post to reduce parser ambiguity.
  5. Authentication: Keep SPF, DKIM, and DMARC passing for the visible From domain.
  6. Monitoring: Alert on endpoint failures so one-click unsubscribe does not silently regress.
I would also keep unsubscribe endpoints separate from fragile marketing-site infrastructure. A campaign landing page can tolerate tracking scripts and design changes. A one-click unsubscribe endpoint needs predictable HTTP behavior, low latency, and simple logging.

Views from the trenches

Best practices
Log method, status, and token result for every unsubscribe endpoint request you receive.
Keep one-click POST handling separate from pages that require sessions or scripts.
Send test messages to real Gmail inboxes and inspect delivered headers before release.
Use opaque tokens and idempotent updates so repeated requests return the same result.
Common pitfalls
Blocking POST at a firewall makes Gmail's first unsubscribe attempt fail silently.
Relying only on a preference-center GET page breaks one-click unsubscribe handling.
Testing template headers misses changes added by the final sending infrastructure.
Treating mailto as the main Gmail path leaves HTTPS POST behavior untested in release checks.
Expert tips
Place List-Unsubscribe before List-Unsubscribe-Post to match common working examples.
Return a success status quickly, then finish slow suppression work behind the scenes.
Keep the GET page useful, but make POST the source of truth for one-click requests.
Watch authentication health because Gmail UI display depends on sender trust signals too.
Marketer from Email Geeks says Gmail can withhold its unsubscribe button when sender or link-domain trust is weak.
2024-02-27 - Email Geeks
Marketer from Email Geeks says working examples often place List-Unsubscribe before List-Unsubscribe-Post.
2024-02-27 - Email Geeks

What I would fix first

The first fix is the endpoint. If Gmail's first popup does not unsubscribe the user and the second popup opens the website, assume POST is failing until your logs prove otherwise. Make the published HTTPS URL accept one-click POST, return success, and unsubscribe based on the opaque token.
After that, clean up the delivered headers, keep a mailto fallback where it helps other clients, and verify SPF, DKIM, and DMARC. Suped is the practical place to keep that ongoing monitoring because it connects authentication, DNS, blocklist checks, and issue remediation instead of leaving unsubscribe debugging as a one-off inbox test.

Frequently asked questions

DMARC monitoring

Start monitoring your DMARC reports today

Suped DMARC platform dashboard
What you'll get with Suped
Real-time DMARC report monitoring and analysis
Automated alerts for authentication failures
Clear recommendations to improve email deliverability
Protection against phishing and domain spoofing