On this page
- what this guide does
- where the tool lives, and what you need
- the workflow in 5 steps
- what every field shows
- the "Scrape Again" button — what it actually does
- the warning catalog — every message decoded
- the Graph API equivalent — script your rescrapes
- the Batch Invalidator — flush many URLs at once
- what the Debugger does NOT do
- platform parity — WhatsApp, Instagram, Messenger, Threads, LinkedIn, X
- the publish-workflow recommendation
- why your previews still break after a clean Scrape Again
- frequently asked
- related
what this guide does
This is the full reference for the Facebook Sharing Debugger. Every field on the page is named, every warning message is decoded with cause and fix, the Graph API rescrape endpoint is documented with auth details, the Batch Invalidator is covered for site-wide cache flushes, and the platform parity story (WhatsApp uses the same crawler; Instagram has separate but related mechanics; LinkedIn has a different tool) is explained.
If you got here because your preview is showing the wrong image, title, or won't update — that's the symptoms article. If you got here because you're inside the Debugger and need to know what every button does — you're in the right place.
where the tool lives, and what you need
The Sharing Debugger sits at https://developers.facebook.com/tools/debug/.
It requires a logged-in Facebook account. It does not require a Meta Developer account, despite the developers.facebook.com URL. A plain personal account works. The confusion is widespread — most third-party guides assume otherwise — but it isn't true.
The tool was previously called the Open Graph Object Debugger (pre-2016) and is still referenced by that name in older blog posts and CMS plugin docs. Same surface, renamed.
Three sibling tools share the same root:
| Tool | URL | What it does |
|---|---|---|
| Sharing Debugger | /tools/debug/ |
Inspect and re-scrape a single URL |
| Batch Invalidator | /tools/debug/sharing/batch/ |
Re-scrape up to 50 URLs at once |
| Open Graph Object Debugger | /tools/debug/og/object/ |
Deprecated; redirects to Sharing Debugger |
the workflow in 5 steps
- Paste your URL into the input field. Query parameters or bare canonical both work — Facebook will tell you which one it treated as canonical.
- Click Debug. Facebook either reads its cached scrape or fetches the URL fresh.
- Read what comes back. Preview card, Time scraped, Response Code, Fetched URL, Canonical URL, Object Properties, Server Response Information, Warnings.
- Click Scrape Again if the cached data is stale. This forces a fresh fetch and updates the cache for that URL.
- Recheck the preview matches what you intended. If it does, you're done. If not, the warning catalog below tells you why.
what every field shows
After you click Debug, the Debugger renders a stack of sections in a fixed order:
Sharing Preview card. Title/description/image as Facebook would render in feed. The "did I succeed?" gut-check.
Time scraped. When Facebook last fetched the page — relative time with absolute timestamp on hover. If it predates your most recent edit, the Debugger is showing stale data.
Response Code. HTTP status from the last fetch. Anything other than 200 is a problem.
Fetched URL. The URL Facebook actually scraped after following redirects. If it differs from what you pasted, each URL in the chain gets its own cache entry.
Canonical URL. What Facebook treats as the canonical destination, driven by <link rel="canonical"> or og:url. Tracking-parameter variants collapse to the canonical for cache purposes if canonicalization is set up correctly.
Object Properties. The parsed Open Graph and standard meta tags Facebook recognized. The "what did Facebook actually see?" panel — the one you stare at when debugging.
Server Response Information. Raw HTTP details: content-type, content-length, response time, headers. Useful for diagnosing CDN/firewall blocks that serve different headers to facebookexternalhit.
Warnings That Should Be Fixed. Covered exhaustively below.
og:image preview. The image Facebook pulled, at the size it would render. Empty slot with an og:image declared = image-fetch problem.
Raw Open Graph Tags. Collapsed by default. Expand to cross-check Facebook's parse against your source HTML character-for-character.
Batch Invalidator link. Quietly placed at the bottom right.
the "Scrape Again" button — what it actually does
Scrape Again forces Facebook to re-fetch the URL and update its cache. Under the hood it's POST https://graph.facebook.com/?id={URL}&scrape=true — the UI is a thin wrapper.
- Per-URL only. Clears cache for the one URL. Does not propagate to other URLs on your domain.
- Rate-limited informally to roughly once per ~30 seconds per URL via the UI. Hammering it can do nothing or return errors; wait 60 seconds if you hit a wall.
- Page reloads with new Time scraped and updated fields after click.
- ~30-day automatic re-scrape. Facebook re-scrapes known URLs roughly once every 30 days on its own. Meta doesn't publish the exact number; the figure is widely cited in third-party docs. We use ~30 days as shorthand.
- Past shares aren't retroactively updated. Future shares get the fresh preview; anything already in feed keeps its cached version.
If Scrape Again doesn't fix your preview, the problem isn't cache. The warning catalog below is the next stop. Underlying causes are in the troubleshooting article.
the warning catalog — every message decoded
Each warning Meta surfaces in the "Warnings That Should Be Fixed" block gets its own subsection. Exact message, severity, cause, fix.
Inferred Property
Message: "The 'og:[X]' property should be explicitly provided, even if a value can be inferred from other tags." Severity: Cosmetic now, cause of future failure.
Facebook fell back to your <title> for og:title, or to a body image for og:image. The preview renders fine but the inference is brittle to layout changes and not guaranteed across all Facebook surfaces (in-feed, share dialog, Messenger, Threads). Fix: add the explicit <meta property="og:title" content="…">. For the upstream causes of why a tag ends up missing or inferred, see the full causes list.
Missing Required Property
Message: "The following required properties are missing: og:url" (or og:type, og:title, og:image).
Severity: Blocks rich preview.
The minimum working set is og:title, og:type, og:image, og:url. Without them the preview degrades to a stripped-down link card or fails entirely. Fix: add the missing tags to <head>.
Provided og:image, [URL], could not be downloaded
Message: "Provided og:image, [URL], could not be downloaded or is too small." Severity: Blocks image.
The most common image warning. The crawler got a non-200, a refusal, a timeout, or content that didn't decode as an image. Diagnostic ladder:
- Open the image URL in incognito. If it doesn't load for a logged-out user, the image is behind auth — fix server-side.
- Check your CDN/WAF for
facebookexternalhit/1.1user-agent blocks. Cloudflare Bot Fight Mode is a frequent culprit. WhitelistfacebookexternalhitandFacebot. - Confirm the URL is absolute.
/images/preview.pngis invalid inog:image; it must behttps://yoursite.com/images/preview.png. - Check the format. PNG, JPG, GIF reliable. WebP has been spotty — serve a PNG/JPG fallback.
- Check it's publicly accessible — no signed URLs with expiry, no IP allowlists, no
Referer-gated access. - Verify from terminal:
curl -A "facebookexternalhit/1.1" -I https://yoursite.com/images/preview.png. If curl returns 200 and the Debugger can't fetch, you have an IP-based block.
For the full inventory of CDN-specific gotchas, see common reasons og:image fetches fail.
Image size is too small
Message: "Image '[URL]' will not be displayed as it is smaller than the minimum required size of 200×200 pixels." Severity: Blocks rich preview.
Meta's minimum is 200×200 px. Fix: use a larger image. The recommended size is 1200×630 px (1.91:1) — crops cleanly into the in-feed card, Messenger preview, and share dialog.
The og:image is too large
Message: "Provided og:image URL [URL] is too large." Severity: Blocks image.
Stated upper bound is 8 MB. This warning is famously unreliable — Kinsta documented receiving it on a 160 KB file. Fix: Scrape Again 30 seconds later (often clears). If it persists, downsize to under 1 MB. There's no benefit to an og:image over ~500 KB — Facebook resizes anyway.
Server response time was X seconds
Message: "Server response time was X seconds, which may cause issues for sharing or loading the page." Severity: Cosmetic; may indicate timeout risk.
Facebook expects responses within ~5 seconds. Above that the crawler may time out. Common causes: cold-start CDN edges, expensive synchronous queries on render, SSR waiting on slow third-party APIs. Fix: profile your response time for the facebookexternalhit user agent specifically; some middleware routes bots through a different (slower) path.
Redirect Path warning
Message: "Object at URL has been redirected to '[URL]'." Severity: Informational; hides cache fragmentation.
Each URL in the redirect chain (e.g. http://yoursite.com → https://yoursite.com → https://www.yoursite.com) gets its own cache entry. Scrape Again on the first doesn't touch the rest. The most-missed source of "I scraped it and it's still wrong." Fix: settle on a single canonical hostname and scheme; resolve in one hop server-side; share only the final canonical externally. For the full explanation, see redirect-chain caching explained.
The 'og:url' property should be explicitly provided
Severity: Cosmetic; cache fragmentation risk.
Without explicit og:url, Facebook uses the URL it was given as the cache key — so ?utm=ig and ?utm=fb of the same page get separate cache entries and separate previews. Fix: declare <meta property="og:url" content="https://canonical-url-no-params/"> matching your canonical.
The following required properties are missing: fb:app_id
Severity: Cosmetic; Insights only.
You do not need an fb:app_id for sharing to work. It's required only for Facebook Insights data on shares. Ignore if you don't care about Insights. Fix (if you want Insights): create a Meta app, get the app ID, add <meta property="fb:app_id" content="…">.
Provided og:image, [URL], is not yet available
Severity: Temporary.
The image downloaded but is still being processed asynchronously (resize, format normalization, Meta CDN caching). Common on first scrape of a new URL. Fix: wait 60 seconds, click Scrape Again. Self-resolves.
Object at URL was not of expected type
Severity: Rare; config mismatch.
og:type declares one thing (article) while other tags or page structure imply another. Fix: align og:type with the page. Most marketing pages = website; blog posts = article (which then expects article:published_time); e-commerce = product.
Image not provided
Severity: Blocks rich preview.
No og:image found and no fallback inferable. Preview renders as a plain link card with no thumbnail. Fix: add og:image. Always. 1200×630 PNG at the recommended size is the default that works everywhere.
og:image:width and og:image:height should be provided
Severity: Cosmetic; improves async processing.
With explicit dimensions, Facebook can render the preview slot before the image finishes async processing — so first-share rendering doesn't fall back to no-image. Fix: add <meta property="og:image:width" content="1200"> and <meta property="og:image:height" content="630"> adjacent to og:image.
Open Graph object missing
Severity: Cosmetic for most use cases.
Facebook read your tags but didn't persist a Graph object for this URL. Usually happens on URLs that have never been shared and never been Debugger-touched. Fix: click Scrape Again. Or POST scrape=true via the Graph API on publish.
Page Not Found / 404
Message: Varies — "URL returned a bad HTTP response code (404)", "Could not retrieve data from URL", or "The crawler failed to connect to the host." Severity: Blocks everything.
The crawler couldn't reach the URL. Fix ladder:
- Open the URL in a browser. Does it load?
- Test as the FB user agent:
curl -A "facebookexternalhit/1.1" -v https://yoursite.com/page. If a regular curl works but the FB UA fails, your server treats bots differently — WAF rules, bot-protection middleware, or a CDN edge that rejects non-browser user agents. - Check no IP firewall blocks Meta's IP ranges. Geo-fencing and anti-DDoS layers often reject them silently.
- Confirm
robots.txtdoesn't blockfacebookexternalhit. (Meta's crawler does respect robots.txt for most paths, with documented exceptions.)
For upstream causes — CDN, WAF, redirect loops, geo-blocks — see why Facebook can't reach your URL.
the Graph API equivalent — script your rescrapes
For anyone manually clicking Scrape Again in a deploy script: skip the click, hit the endpoint directly.
curl -X POST \
-F "id={YOUR_URL}" \
-F "scrape=true" \
-F "access_token={ACCESS_TOKEN}" \
"https://graph.facebook.com/v19.0/"
Auth requirement. Since October 16, 2017, all Graph API calls including scrape require an access token. Use an app access token (server-to-server) generated from any Meta App. No special permissions or review needed for the scrape call. Generating an app token is one POST against oauth/access_token with your app ID and secret; the result is long-lived and suitable for server-to-server use.
Pre-v2.10 note. Before Graph API v2.10, a GET against /{url} would trigger a scrape. That behavior was removed — POST with scrape=true is the only path now. Older gists showing GET-based rescrape are out of date.
Response. The same Open Graph object the Debugger would display, in JSON. Shape: id, og_object (title, type, image, description, url), share counts, error block if scrape failed.
Wire it into:
- Every publish hook — POST a scrape request as the last step. First social share has a fresh cache.
- Every meta-tag edit — scrape the affected URL the moment the edit saves.
- Site migrations — loop through your sitemap, rate-limit to ~600/hour to avoid throttling.
- Template changes affecting many pages — script the API (hundreds to thousands) or use the Batch Invalidator (tens to small hundreds).
Rate limits are not publicly documented for scrape specifically. ~600/hour per app token is safe in practice; above that expect intermittent throttling.
the Batch Invalidator — flush many URLs at once
At https://developers.facebook.com/tools/debug/sharing/batch/. Up to 50 URLs at a time, one per line. Meta's docs say space-delimited but newline-delimited works. Click Submit; Facebook re-scrapes all of them and returns new previews in a list.
Use it for: post-migration hostname changes, post-template og:image updates, post-CMS bulk edits, pre-launch warm-up of 20–50 new URLs. Don't use it for: routine single-page debugging (use the Debugger), or anything above a few hundred URLs (script the API in batches of ~50 per minute).
Same auth as the Debugger — plain Facebook account, no Developer account. The 50-URL limit is per submission, not per session; paste 50, submit, paste another 50, submit again.
what the Debugger does NOT do
The tool has hard edges. Knowing them prevents debugging the wrong thing.
Doesn't execute JavaScript. If your og: tags are injected client-side by React, Vue, or hydration, the crawler sees nothing. Server-render OG tags or use a prerender service.
Doesn't follow CDN auth. Signed URLs, IP-restricted access, and Referer-based access control block the crawler. Make og:image URLs publicly accessible without auth.
Doesn't simulate user-agent variation. The Debugger always crawls as facebookexternalhit/1.1. Our User-Agent checker lets you spoof the FB crawler header without writing curl commands. See how user-agent detection works for in-app browsers — same UA-based branching can create crawler-detection problems.
Doesn't validate per-locale og: tags. With og:locale:alternate set, the Debugger shows the primary locale only.
Doesn't help with Twitter, LinkedIn, or WhatsApp specifically. It's Facebook-only (with the WhatsApp asterisk below). LinkedIn has Post Inspector. Twitter's Card Validator is degraded. WhatsApp has no debugger UI at all.
Doesn't reset cache for URLs that haven't been shared — nothing to clear.
Doesn't reveal IP-level blocks. A firewall that drops Meta's IP range shows "could not be downloaded" with no indication that it's IP-specific. Diagnose with curl -A "facebookexternalhit/1.1" -v {URL} from a non-blocked host.
platform parity — WhatsApp, Instagram, Messenger, Threads, LinkedIn, X
The Sharing Debugger nominally tests Facebook. In practice it tests a partially overlapping set of surfaces.
WhatsApp. Shares the facebookexternalhit crawler with Facebook. The Sharing Debugger is the closest thing to a WhatsApp debugger — if Facebook's preview is correct after Scrape Again, WhatsApp picks up the fresh data on its next cache refresh (24–48 hours typically; shorter than Facebook's ~30 days). No WhatsApp UI to clear cache and no Scrape Again equivalent. WhatsApp also fetches preview metadata as you type a URL in chat (before send), so caching is even more aggressive for common URLs. If you need a WhatsApp preview faster than 24 hours, append a benign query parameter — new cache entry, scraped fresh.
Instagram. Does not use Open Graph for in-feed link previews — bio links render as plain URLs, DM-shared links as text. Open Graph matters for link stickers in Stories, which pull og:title and og:image on first scrape. No Instagram-specific debugger; the Sharing Debugger is your only surface. (See the Instagram in-app browser deep-dive for how Instagram renders links and why its webview breaks downstream sessions.)
Messenger and Threads. Both pull from Facebook's cache. Same fix path as Facebook.
LinkedIn. Separate crawler (LinkedInBot/1.0), separate cache. Use Post Inspector for LinkedIn previews. Cache is ~7 days from first share. Don't assume Sharing Debugger results predict LinkedIn behavior.
X (Twitter). Twitter Cards. The Validator at cards-dev.twitter.com/validator was effectively deprecated in 2023 and now returns inconsistent results. If your Facebook preview is correct AND you have twitter:card, twitter:title, twitter:image as fallbacks (most CMSs emit these alongside Open Graph), X usually renders correctly. If a post fails on X specifically with no clear cause, the account may be shadowbanned and previews suppressed independently of metadata — that's account-level, not page-level.
Summary: one debugger covers Facebook + WhatsApp + Messenger + Threads. LinkedIn has its own. Instagram is partial. X has effectively none.
the publish-workflow recommendation
- On publish hook: POST
scrape=truefor the published URL. First social share has fresh data. - On meta-tag edit: scrape the affected URL on save.
- On template change: Batch Invalidator UI for tens, Graph API loop for hundreds, batches of 50 for thousands.
- On site migration: sitemap + API loop, rate-limited to ~600/hour. Don't try this through the UI.
- For manual checks: Debugger UI, paste, Debug. Bookmark this page; jump to the warning section.
This eliminates the "I shared the link before realizing the og:image was wrong" failure mode. Every URL pre-scraped at publish; first share always fresh. If the cache is fresh and the preview is still wrong, the troubleshooting article is the next stop.
why your previews still break after a clean Scrape Again
The Sharing Debugger fixes about 80% of preview problems by re-fetching and clearing cache. The remaining 20% usually splits into:
- CDN/firewall blocking the FB crawler (most common; usually Cloudflare Bot Fight Mode or a WAF rule)
- JavaScript-rendered OG tags (React/Vue apps without SSR; crawler sees empty
<head>) - The in-app browser problem — viewer clicks the share, lands in TikTok or Instagram's webview, and the destination loads logged-out even though the preview rendered perfectly
That last category isn't a preview problem. It's the logged-out-from-the-in-app-browser problem. The Sharing Debugger can't help — it isn't about preview metadata, it's about what happens after the click. The preview is correct. The page loads. The viewer is logged out of Amazon, Spotify, OnlyFans, their checkout. They bounce.
The mechanics: Facebook's in-app browser (and TikTok's, Instagram's) runs as a separate WKWebView or Android WebView with its own isolated cookie jar — the viewer's logged-in Safari or Chrome session doesn't transfer. The in-app browser cookies explainer is the engineering view. For how this lands in the wild, see Amazon links failing from TikTok, Substack subscribe drop-off from Instagram, or Spotify links not opening the app from TikTok — destinations where the Facebook preview was textbook-perfect and the conversion still cratered.
linkboo handles the half of the funnel that happens after the click. Every linkboo link bounces out of in-app browsers into the viewer's default browser before the destination loads, so cookies, autofill, and saved logins survive. If your previews are clean but your funnel isn't, that's the gap. Start free on the free plan →.
frequently asked
Do I need a Meta Developer account? No. A plain Facebook account works.
Why does Facebook cache previews so aggressively? Rendering link cards in feed at Facebook's scale would be impossible if every share re-fetched the source page. Cache is the price of fast feed rendering.
How long until Facebook re-scrapes my URL automatically? Approximately 30 days for URLs that have been shared at least once. Meta does not publish an exact figure; ~30 days is consistent across third-party documentation. Never-shared URLs are scraped fresh on first share.
What's the difference between the Sharing Debugger and the Open Graph Object Debugger? Same tool. "Open Graph Object Debugger" is the pre-2016 name.
Can I debug other people's URLs? Yes. It's a public tool. Any URL you can reach in a browser, you can debug.
Does Scrape Again update shares that already happened? No. Past shares retain the cached preview from the time of share. Future shares get the fresh preview.
Does fb:app_id matter for the preview to render? No. Required only for Facebook Insights data.
What if my image is .webp? Convert to PNG or JPG and re-test. WebP support has been unreliable.
My preview is still wrong after Scrape Again — now what? Walk through the full causes list. The cache-vs-crawl-vs-CDN diagnostic tree picks up where this guide stops.
Is there a paid tier with more features? No. Sharing Debugger and Batch Invalidator are free. Rate-limit behavior is the same for all accounts.
related
- Facebook link preview not updating — every cause and fix — the symptoms-and-causes companion to this tool walkthrough
- The in-app browser logged-out problem — when fresh previews aren't enough
- In-app browser cookies, explained — the engineering view of why webview sessions don't carry
- TikTok in-app browser deep-dive
- Detect in-app browsers by User-Agent
- In-app browser detector tool — paste a URL, see how it behaves inside TikTok/Instagram