If your OpenGraph image isn't showing, it's almost always one of eight causes: a cached old version, a relative or broken absolute URL, an image behind auth or hotlink protection, the wrong size or format, missing og:image:width / og:image:height, a robots.txt block for the platform crawler, a 4xx response on either the page or the image, or a platform-specific gotcha. Work through them in order.
Is your image URL absolute and publicly fetchable?
The crawler lives outside your network. It sees your site the same way a stranger with no cookies does. The most common mistake is a relative og:image path — unfurlers resolve it against the page URL but some proxies, redirects, and root-relative paths turn it into a broken URL.
Test it from your terminal:
# Replace with your actual og:image URL
curl -I https://example.com/og.png
# Should return 200 with Content-Type: image/png (or image/jpeg)
# If you see 403, you have hotlink protection or a WAF rule blocking the botIf you're on Cloudflare, check "Security → Bots" and "Security → WAF" for rules that block empty-referer or non-browser User-Agents. The major crawlers identify themselves as facebookexternalhit, Slackbot, Discordbot, LinkedInBot, Twitterbot, and WhatsApp.
Is the crawler serving a stale cache?
If the preview used to work and now shows the wrong image, it's a cache. Each platform has a different TTL:
- LinkedIn: 7 days. Re-scrape at Post Inspector.
- Facebook: ~24 hours. Click "Scrape Again" in the Sharing Debugger.
- Slack: 24 hours. No official re-scrape — append
?v=2to the URL or wait. - Discord: indefinite per URL. Changing any query param forces a refetch.
- X: ~1 week. No re-scrape tool since the Card Validator retired.
Is the image the right size and format?
Facebook silently rejects images smaller than 200×200 and warns on anything under 600×315. WebP is inconsistent across Slack and Discord clients. The universal safe format is PNG or JPEG at 1200×630. See the dedicated OpenGraph image sizes guide for per-platform numbers.
Also: keep the file under 5 MB (X and LinkedIn enforce), ideally under 1 MB so the crawler doesn't time out.
Are you declaring width and height?
og:image:width and og:image:height let Discord, Slack, and some proxies render the preview layout before the image has finished downloading. Without them, certain clients skip the image entirely or show a tiny placeholder.
<meta property="og:image" content="https://example.com/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">Is the crawler allowed by robots.txt?
If you have a strict robots.txt, make sure the social crawlers are allowed. Common offenders:
User-agent: facebookexternalhit
Allow: /
User-agent: Slackbot
Allow: /
User-agent: LinkedInBot
Allow: /
User-agent: Discordbot
Allow: /
User-agent: Twitterbot
Allow: /
User-agent: WhatsApp
Allow: /
User-agent: TelegramBot
Allow: /Is your server returning 200 for the image?
Bots often get different responses than browsers. A CDN geoblock, a sign-in wall, or a rate-limit rule can return 403 or 404 to the bot even though the image loads fine in your browser. Check your access logs and filter by the platform User-Agent to see what the crawler actually received.
Also verify the <head> of your page itself is reachable. If og:url returns 401/403 to the bot, it gives up before fetching the image.
Platform-specific gotchas
Requires a valid Content-Type header on the image response. If your CDN serves it as application/octet-stream, Slack ignores the image. Set Content-Type: image/png explicitly.
Strips previews for pages that send a strict Content-Security-Policy with frame-ancestors none. It also requires og:image:width and og:image:height to render inline. WebP fails on older desktop clients.
Requires twitter:card to be set for any rich preview. Without it, X falls back to a plain text link even if OpenGraph is present.
The Sharing Debugger is authoritative. If it shows no image, no other test matters — fix what the debugger reports first.
Aggressively caches for 7 days. If you test with an image URL, then change the URL, LinkedIn may continue to show the old one for up to a week — use Post Inspector to force re-scrape.
How to force a re-fetch
If you've fixed the underlying issue, you still need to bust the cache. In rough order of reliability:
- Use the platform's debugger (Facebook Sharing Debugger, LinkedIn Post Inspector). Click "Scrape Again" or equivalent.
- Append a cache-busting query param to your canonical URL:
https://example.com/page?v=2. Updateog:urlto match. This creates a fresh cache entry. - Change the og:image URL itself —
og.png→og-v2.png— if the image-level cache is the problem. - Wait it out — caches expire on the TTLs above.
Why is the old image still showing?
This is the single most-asked OpenGraph question. Nearly always it's a cache, not a tag problem. Run the platform's debugger against your URL and look at the "last scraped" timestamp. If it's before your change, force a re-scrape. If it's after your change and the image is still old, check two things: is your server actually serving the new image at that URL, and is there a CDN between you and the crawler that's serving a stale version?
Once the image loads, generate the full correct tag set with the Meta Tag Generator or consult the OpenGraph cheatsheet.