Why your link preview shows the wrong image

Almost always because the platform cached a card it built earlier and hasn’t looked at your page since. The tags you just fixed are correct; the copy the platform is showing was made before you fixed them. Editing your HTML does not reach into their cache.

That single fact explains the large majority of “I changed it and nothing happened” reports. The remaining cases have a small number of distinct causes, and they’re all identifiable.

First: check what the crawler sees, not what you see

Before assuming a cache, confirm the tags are actually in the HTML that a server sends — because your browser and a crawler can see different pages.

curl the URL and read the head:

curl -s https://example.com/page/ | grep -i 'og:\|twitter:'

If the tags aren’t in that output, they aren’t in the HTML, and no amount of cache-clearing will help. The usual reason is the next section.

Cause 1: the tags are added by JavaScript

Preview crawlers often don’t run JavaScript. If your Open Graph tags are injected client-side — by a framework, a tag manager, or an analytics snippet — the crawler fetches your page, finds no tags, and falls back to guessing.

The symptom is distinctive: previews look right in tools that render the page, and wrong in every actual chat app.

The fix is server-rendered tags. They have to be in the initial HTML response.

Cause 2: the image URL is relative

<meta property="og:image" content="/images/preview.png">

Some crawlers resolve this against the page URL. Some don’t and simply find no image. Always absolute, always HTTPS.

Cause 3: the platform cached the card

The big one. Once a card exists for a URL, it’s reused. Cache lifetimes are long, aren’t reliably documented, and differ per platform.

Two ways out:

Ask for a re-fetch. Every major platform has a debug or preview tool that fetches a URL fresh and updates its cache. Paste the URL, look at what it found, re-scrape. This is the correct fix and it works per-platform, one URL at a time.

Change the URL. A new URL has no cache entry, so it gets a fresh look. Adding a query parameter counts. This is a workaround rather than a fix — you’ve now got two URLs for one page, which is untidy for sharing and for analytics — but it’s immediate and needs nobody’s tooling.

Note that the image is cached separately from the card. Replacing preview.png in place often leaves the old picture in circulation even after a successful re-scrape, which is the argument for versioned image filenames.

Cause 4: the image failed to download in time

The crawler read your tags, tried to fetch the image, and gave up. Then it cached a card with no image.

Causes: a large file, a slow origin, an image behind a redirect chain, an image requiring authentication, or hotlink protection that blocks unknown user agents.

Test it directly — fetch the image URL with no cookies and check the status and size:

curl -sI https://example.com/images/preview.png

You want a 200, a sensible content-type, and a size in the hundreds of kilobytes rather than megabytes.

Cause 5: redirects

If the shared URL redirects, behaviour varies. Most crawlers follow, and then it matters which page’s tags they read and whether og:url points at the destination. A chain of several redirects, or a redirect to a different host, is where previews get strange.

Keep it to at most one redirect, and make sure the final page’s og:url matches its own canonical address.

Cause 6: there are two sets of tags

More common than it sounds. A theme adds Open Graph tags, then a plugin adds its own, and the page carries two og:image declarations. Which one wins depends on the parser — usually the first, sometimes the last.

The grep above shows this immediately: if you see duplicates, remove one source.

Cause 7: it’s not your image, it’s their crop

Sometimes the right image is being used and looks wrong. A tall or square image in a wide card gets centre-cropped, so a logo at the top of a square image vanishes.

If the card shows part of your image, this is a dimensions problem, not a cache problem. 1200 × 630 solves it.

A diagnostic order that works

  1. curl the page and confirm the tags exist in the raw HTML. Fixes the JavaScript and duplicate-tag cases.
  2. Confirm og:image is an absolute HTTPS URL.
  3. curl -I the image and confirm it returns 200 at a reasonable size.
  4. Run the platform’s own debug tool, read what it reports, and re-scrape.
  5. If a re-scrape shows the new card but real shares still show the old one, the image is separately cached — publish it under a new filename.
  6. If the image appears but cropped, fix the dimensions.

Working through in that order takes a few minutes and identifies the cause rather than guessing at it. The temptation is to jump straight to re-scraping, which fixes cause 3 and leaves you baffled if it was one of the others.