OG Cover
Guides

Why your OG image is not updating, and how to force a refresh

Your link preview is showing the old picture, or no picture at all. Here is what each platform caches, how long it holds it, and the one trick that beats every cache.

Rawand DevBuilder of OG Cover
· 7 min read
Share
The Open Graph card for this post, made with OG Cover

You changed the image, redeployed, pasted the link into Slack, and got the picture from three weeks ago. Or worse: a grey box with the domain name in it. This is the single most common Open Graph problem, and almost every case comes down to one of two things. Either the crawler cached a previous answer, or the crawler never successfully fetched your image in the first place.

Those two have completely different fixes, so the first job is telling them apart.

First, work out which problem you have

Open the page you are sharing and view source. Do not trust your framework's dev tools or a React component you believe renders the tag: look at the HTML the server actually sent. Search it for og:image.

  • The tag is missing from the source. Your image was never the problem. The tag is being injected on the client, and crawlers do not run your JavaScript. Render it server side.
  • The tag is there and the URL is right. You have a caching problem. Skip to forcing a refresh.
  • The tag is there and the URL is wrong. Fix the URL first. The next section is a list of the ways it goes wrong.

Copy the value of the content attribute and paste it into a private browsing window. If the image does not load there, with no cookies and no session, it will not load for a crawler either.

Eight reasons a crawler never got your image

  1. The URL is relative. content="/og.png" is not enough. A crawler resolves og:image on its own, without your page as a base, so it must be absolute and include the scheme: https://example.com/og.png.
  2. It is behind a login, a preview deploy, or basic auth. Crawlers carry no cookies and none of the headers you set. A protected preview URL fails here, which is why the card works locally and breaks in production.
  3. robots.txt blocks it. Several unfurlers, facebookexternalhit among them, read robots.txt before fetching the image. A blanket Disallow: /api/ will quietly kill a card served from an API route.
  4. The content type is wrong. The response has to be image/png, image/jpeg or image/webp. A route that returns text/html on error, or application/octet-stream, gets discarded.
  5. The file is too large. Stay under 5 MB. Some platforms cap lower, and a crawler that times out mid-download treats it as a failure rather than retrying.
  6. It redirects. Some crawlers follow redirects on og:image and some do not. Point at the final URL.
  7. It is not reachable from outside your network. localhost, a private IP, or an internal CDN hostname all look fine to you and are unreachable to everyone else.
  8. The tag is inside <body>. Meta tags belong in <head>. Some parsers stop reading at the first <body> tag and will never see it.

What each platform caches, and for how long

Every platform caches the first successful response it got, and a failure counts as a response. That last part is what catches people: if the crawler hit your page during a deploy and got a 404 for the image, some platforms will serve that empty result for days without trying again.

PlatformRoughly how longHow to force a refresh
FacebookAround 7 daysSharing Debugger, then Scrape Again
LinkedInAround 7 days, historically longerPost Inspector, which re-crawls on submit
X (Twitter)Around 7 daysNo public debugger. Change the URL
SlackAround 30 minutes for the page, far longer for the imageNo debugger. Change the URL
DiscordHours to daysNo debugger. Change the URL
WhatsApp and iMessageEffectively indefinite per URLNo debugger. Change the URL
GoogleUntil the next crawlRequest indexing in Search Console

Treat those durations as folklore rather than contract. None of them are published guarantees, and they change.

Forcing a refresh

The reliable way: change the URL

Caches are keyed on the image URL. A URL that has never been seen cannot be stale. This is the only method that works on every platform at once, including the ones with no debugger, and it is what to reach for when something is going out in ten minutes.

<!-- Before -->
<meta property="og:image" content="https://example.com/og/launch.png" />

<!-- After: same file, new cache key -->
<meta property="og:image" content="https://example.com/og/launch.png?v=2" />

<!-- Better: a content hash, so it changes exactly when the image does -->
<meta property="og:image" content="https://example.com/og/launch.8f3c21.png" />

A query string is enough for most platforms. A new file name is enough for all of them, and it is worth the extra step for anything you cannot re-announce.

The polite way: ask the platform to re-crawl

  • Facebook, WhatsApp and Instagram share one cache. Run the page URL through the Sharing Debugger and press Scrape Again. The debugger also prints which tags it found, which makes it a useful validator even when nothing is broken.
  • LinkedIn re-crawls whenever you submit a URL to the Post Inspector. LinkedIn has historically been the worst offender for long caching, so check here before you announce anything there.
  • X, Slack, Discord and iMessage publish no debugger. Change the URL, or share the link into a private channel once to warm the cache with the correct version before the real post goes out.
  • Google picks the image up on its next crawl. Use URL Inspection in Search Console and request indexing if you need it sooner.

While you are in there, check the whole tag set

Most broken cards are missing more than the image. This is the full set worth having, and it is what the Ship It section of the OG image generator builds for you from whatever you type into the editor.

<meta property="og:title" content="Your headline" />
<meta property="og:description" content="One supporting sentence." />
<meta property="og:image" content="https://example.com/og/launch.png" />
<meta property="og:url" content="https://example.com/post" />
<meta property="og:type" content="article" />
<meta name="twitter:card" content="summary_large_image" />
  • twitter:card set to summary_large_image is what turns the X preview from a small square thumbnail into a full width card. Without it the image is technically working and still looks broken.
  • og:url should be the canonical URL. It is what platforms key their cache on, and it stops three tracking-parameter variants of one page being cached as three different previews.
  • You do not need twitter:image. X falls back to og:image. Set it only when you deliberately want a different picture on X.
  • Adding og:image:width and og:image:height lets a platform reserve the right space before the file finishes downloading. Use the real numbers, usually 1200 and 630.

How to stop it happening again

  1. Version the file name, not just the query string. If the image is generated at build time, put a content hash in the name. The problem disappears permanently, because the URL then changes exactly when the picture does.
  2. Never point og:image at a URL you intend to overwrite in place. That is the setup that produces this bug.
  3. Validate before you announce, not after. Run the URL through the Sharing Debugger and the Post Inspector as the last step of shipping, while a mistake is still cheap to fix.
  4. Check the card at a small size. WhatsApp and iMessage render previews at a fraction of the size of a Slack unfurl. A headline that works at full size can be unreadable there, so keep it short and keep it away from the edges.

The two minute checklist

  1. View source on the live page and confirm og:image is in the HTML the server sent.
  2. Confirm the URL is absolute, with https:// on the front.
  3. Open that URL in a private window. It has to load with no login.
  4. Confirm robots.txt does not disallow the path it sits on.
  5. Confirm the response is under 5 MB with an image content type.
  6. Add ?v=2 to the URL, or rename the file.
  7. Run the page through the Sharing Debugger and the Post Inspector.
  8. Share into a private channel to check the result before it goes public.

If the picture still has not moved after all of that, the tag on the page is almost certainly not the tag you think it is. Go back and view source one more time.