Why Twitter Link Preview Images Are Not Showing and How to Fix Them
Fix missing X/Twitter link images by checking served metadata, card type, image access, crawler rules, and stale previews.
Check the HTML that your shared URL actually serves, then verify the card type, image URL, and crawler access. A correct setting in a CMS is not enough if the rendered page omits or overrides the tags. A small thumbnail usually means the page requests a summary card instead of a large-image card. An image that works while you are logged in can still be unreachable to a crawler.
Fix the problem in this order
- Open the exact URL people share and inspect its final HTML source.
- Find
twitter:card,twitter:title,twitter:description, andtwitter:image. - Remove duplicate or conflicting tags generated by your theme, CMS, or SEO plugin.
- Set the layout deliberately. Use
summary_large_imagewhen you expect a prominent image. - Use an absolute HTTPS image URL that an unauthenticated client can fetch.
- Check redirects, firewall rules, authentication, hotlink protection, and robots directives.
- Validate the image response from outside your logged-in browser.
- Republish the page and allow for platform caching before judging the result.
What the metadata should look like
Place one coherent set of tags in the document <head>. The following example requests a large image card:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Why database indexes become slow">
<meta name="twitter:description" content="A practical guide to diagnosing index performance.">
<meta name="twitter:image" content="https://example.com/social/database-indexes.png">
<meta property="og:title" content="Why database indexes become slow">
<meta property="og:description" content="A practical guide to diagnosing index performance.">
<meta property="og:image" content="https://example.com/social/database-indexes.png">
<meta property="og:url" content="https://example.com/database-indexes">
Open Graph fields can provide fallback values when platform-specific fields are missing, but they do not choose the X card layout. The twitter:card value does that.
Why inspect the served HTML?
CMS controls are inputs, not proof of the final response. A plugin may add a second image tag, a theme may emit an older title, or server-side rendering may omit metadata entirely. View the page source or fetch the URL directly and inspect what an unauthenticated client receives.
Check the card type first
If the preview has a small thumbnail, inspect:
twitter:card
summary is the compact layout. summary_large_image requests the large-image layout. Choose one intentionally and ensure only one effective value remains after your CMS renders the page.
A large card still needs a usable image. Changing only the card type cannot repair a blocked, missing, or invalid image URL.
Verify that the image URL is fetchable
The value of twitter:image should be a complete HTTPS URL, not a relative path such as /images/card.png. Test the exact URL from a machine that is not authenticated to your site.
curl -I -L 'https://example.com/social/database-indexes.png'
Look for a successful response, a final image URL, and an image content type. Investigate these failure patterns:
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 or 403 | Login, firewall, signed URL, or hotlink rule | Publish the image at a publicly readable URL or adjust the access rule for crawler requests. |
| 404 | Wrong path, case mismatch, or deleted asset | Correct the tag or restore the asset. |
| Redirect loop | HTTP/HTTPS or CDN redirect misconfiguration | Use the final HTTPS URL and remove the loop. |
| HTML returned instead of an image | Error page, login page, or CDN challenge | Serve the actual image bytes at the metadata URL. |
| Works only in a browser | Cookies, referer checks, or bot protection | Test without browser cookies and permit unauthenticated retrieval. |
Choose practical image dimensions and formats
A third-party card guide recommends 1200 × 630 pixels for a large image. Treat that as practical guidance, not a confirmed current X requirement. Keep the file reasonably sized and use a widely supported web image format. The image must be readable at the final card size, with important content away from edges that may be cropped.
Do not rely on a transparent image if the design becomes invisible against an unknown preview background. Generate a dedicated social image instead of reusing a tiny logo or an image that requires client-side JavaScript to render.
Find duplicate and conflicting tags
Search the final source for every occurrence of these names:
twitter:card
twitter:image
twitter:title
twitter:description
og:image
og:title
og:description
Multiple plugins commonly emit different values. Keep one authoritative set. Fix the generator (theme, plugin, template, or server code) rather than appending another set at the end of the document.
Check canonical URLs, redirects, and variants
People may share several URL forms: HTTP and HTTPS, trailing slash and no slash, tracking parameters, or a short link that redirects. Inspect the exact URL being shared and the final response after redirects. Put metadata on the page that ultimately renders and keep its canonical URL consistent.
A query parameter can also select a different template or image. Test the production URL, not only a preview URL in your CMS.
Check crawler access and robots rules
A page can load for you while a crawler is blocked by authentication, IP restrictions, a Web Application Firewall, robots directives, or a CDN bot challenge. Confirm that both the HTML document and the image URL can be requested without a session. Review server logs while making an unauthenticated request, and check whether the response differs by user agent or geography.
Do not assume that allowing your normal browser is equivalent to allowing a social crawler. A challenge page, rate limit, or redirect to login prevents the metadata and image from being read.
Handle stale previews safely
After fixing the HTML and image, an already shared URL may continue to show old data because the platform caches previews. First verify that a fresh request to your URL returns the corrected tags and image. Then preview the link in the X composer, if that facility is available to your account.
Cache duration and refresh behavior can change, so do not promise an immediate update or rely on an exact cache lifetime. A changed URL may produce a new fetch, but it should not replace fixing the original metadata.
A repeatable diagnostic workflow
- Record the exact shared URL. Include its scheme, path, slash, and query string.
- Fetch the page anonymously. Save the response and inspect the rendered head.
- Resolve conflicts. Remove duplicate tags and confirm the intended card value.
- Fetch the image anonymously. Follow redirects and verify that the final response is an image.
- Review access controls. Check robots settings, WAF events, CDN rules, and authentication.
- Check variants. Compare the shared URL with the canonical URL and redirect target.
- Republish and preview. Allow for caching after confirming the live response is correct.
Or skip the browser setup
If you need reliable screenshots of the page or its social image while debugging, ScreenshotNeo provides a single HTTP request and supports PNG, JPEG, WebP, and PDF output. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off.
Only clean shots are billed. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo API documentation for all options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/article -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/article"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/article' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.
Performance, reliability, and cost considerations
- Keep social images static. A directly served file is faster and less fragile than a client-rendered canvas.
- Use a CDN carefully. Confirm that edge rules do not require cookies or challenge automated fetches.
- Reduce redirect chains. Point metadata straight at the final HTTPS image.
- Monitor failures. Log 4xx, 5xx, timeout, and challenge responses for the page and image paths.
- Separate preview debugging from production traffic. Repeatedly fetching large pages or images can consume bandwidth; cache your own diagnostic results.
- Expect cache delay. A successful fix may not change an existing preview immediately.
Troubleshooting checklist
- The exact shared URL returns the intended HTML to an unauthenticated client.
-
twitter:cardis present once and matches the desired layout. -
twitter:imageis an absolute HTTPS URL. - The image URL returns image bytes without login or cookies.
- There is no redirect loop, WAF challenge, or hotlink block.
- Duplicate tags from plugins and themes have been removed.
- The image is large enough for the intended design and has a practical file size.
- The live response is fixed before testing a cached preview.
FAQ
Why does X show a small thumbnail instead of my large image?
Inspect twitter:card. A summary value requests the compact layout; use summary_large_image for the large-image layout.
Do I need both Twitter and Open Graph tags?
Platform-specific tags make the intended result explicit. Open Graph values may act as fallbacks, but Open Graph does not select the X card layout.
Why does the image work when I open it?
Your browser may have cookies or permissions that a crawler does not. Test the image URL anonymously and inspect firewall, authentication, redirect, and CDN behavior.
Will changing the image URL immediately refresh an old post?
Not necessarily. Cached previews can remain stale. Verify the live HTML and image first, then allow time for a new fetch.
Is 1200 × 630 an official current requirement?
The cited third-party guide recommends that size for a large image, but the research did not verify it as a current official X requirement.


