X (Twitter) card not showing an image: the tags X reads
Set twitter:card to summary_large_image, give X an image it can fetch, allow Twitterbot, then test in the post composer. X caches cards for up to 7 days.
LLaunchScaler·Published ·8 min read
An X card shows no image when X either rendered a small summary card instead of a large one, or could not fetch the image. Set twitter:card to summary_large_image, point twitter:image (or og:image) at a public, absolute URL for a JPG, PNG, WEBP or GIF under 5 MB, make sure robots.txt and your firewall let Twitterbot in, then test by pasting the link into the post composer. X caches card data for up to 7 days, so an old card can outlive your fix.
The cards pages on X's developer site no longer load at their old addresses, so the rules below come from X's cards documentation as archived in 2025 and from X's 2022 announcement on the Card Validator. X's current developer documentation has no cards section to replace them.
Which tags does X read for a card?
X reads twitter:* tags first and falls back to Open Graph tags for most of them. twitter:card picks the card type and has no image fallback of its own, so set it explicitly. For a large image card you need twitter:card, a title and an image, either as X tags or as the Open Graph equivalents.
X tag
What it does
Open Graph fallback
Limits X states
twitter:card
Card type: summary, , or
Questions, answered
What people ask about this
01
Why is my Twitter card not showing an image?
Usually X either rendered a small summary card because twitter:card is missing or set to summary, or it could not fetch the image: the URL is private, the file is over 5 MB or not a supported format, or Twitterbot is blocked by robots.txt or a firewall. If you changed the tags recently, X may still be showing its cached card.
og:type (with title and description, "a summary card may be rendered")
Must be summary_large_image for the large image
twitter:title
Title of the content
og:title
Maximum 70 characters
twitter:description
Description of the content
og:description
Maximum 200 characters
twitter:image
Image URL
og:image
Under 5 MB; JPG, PNG, WEBP, GIF; no SVG
twitter:image:alt
Alt text for the image
og:image:alt
Maximum 420 characters
twitter:site
@username of the website
None
Listed as required alongside twitter:site:id
The fallback row for twitter:card explains a common "no image" case. If a page has og:type, og:title and og:description but no twitter:card, X's reference says "a summary card may be rendered." The summary card shows a small square thumbnail, not the wide image people expect, and it crops to a square.
A minimal block that gives X everything it needs, reusing Open Graph for the rest:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@acme">
<meta property="og:title" content="Invoicing software for freelancers">
<meta property="og:description" content="Send invoices in two clicks and chase late payers automatically.">
<meta property="og:image" content="https://www.example.com/og/home-1200x630.png">
<meta property="og:image:alt" content="Acme invoice editor with a paid invoice">
Note the attribute names. X's tags use name="twitter:...", as in X's own examples, and Open Graph uses property="og:...". In Next.js, the twitter field of the metadata object outputs the twitter:* tags, with card: 'summary_large_image' producing <meta name="twitter:card" content="summary_large_image" />.
How do you set X card tags in Next.js?
Use the twitter field of the metadata object, or a twitter-image file beside the page. The metadata field maps each key to its tag, and the Next.js docs note that images there "must be an absolute URL" unless metadataBase is set:
Remember that Next.js merges metadata shallowly: a page that sets its own twitter object replaces the layout's whole twitter object, so a page that sets only title there loses card and can fall back to a summary card. Spread a shared object into each page's twitter field to keep card everywhere.
What image does a large image card accept?
X's large image card supports "an aspect ratio of 2:1 with minimum dimensions of 300x157 or maximum of 4096x4096 pixels," under 5 MB, in "JPG, PNG, WEBP and GIF formats." "SVG is not supported," and only the first frame of an animated GIF is used. X also asks for "a unique image representing the content of the page," not a site logo.
A 1200 x 630 image fits: it is well above the minimum, and at 2:1 X trims about 30 px of height, so keep text away from the top and bottom edges. The same file works for Facebook and LinkedIn; OG image size gives every platform's numbers and the safe area.
X's archived troubleshooting guide maps its error messages to image causes:
Message
Cause X gives
Fix
"Failed to get a proxied URL for the image"
The image "is not publicly accessible on the web," often on staging or an internal network
Serve the image from a public URL
"Invalid Image. This image cannot be fetched."
Image smaller than the minimum, or network lag
Use at least 300 x 157 px (144 x 144 for a summary card); retry
"Fetching the page failed because the request timed out"
Crawlers blocked, robots.txt, a .htaccess deny rule, an image over 5 MB, network lag, or a host blocking X
Remove the block; shrink the image
"Fetching the page failed because the response is too large"
The page response is over X's 2 MB limit
Reduce the HTML response size
Can Twitterbot reach the page and the image?
Twitterbot has to fetch both the page and the image, and X names robots.txt, firewall rules and hosting-level blocks as common reasons it cannot. X's crawler identifies itself as Twitterbot (with a version, such as Twitterbot/1.0) and "implements Google's robots.txt specification," so a Disallow that matches the page or the image path stops the card.
Check robots.txt first. To make sure Twitterbot is allowed, X's guide gives this group:
User-agent: Twitterbot
Disallow:
An empty Disallow: allows everything for that user agent. If your robots.txt blocks a folder like /assets/ or /static/ for all bots, and your card image lives there, add an Allow: line for the image path in the Twitterbot group.
Then check what Twitterbot actually receives:
curl -sI -A "Twitterbot/1.0" https://www.example.com/
curl -sI -A "Twitterbot/1.0" https://www.example.com/og/home-1200x630.png
A 403, a challenge page or a redirect to a login means a firewall, bot-protection rule or authentication layer is answering Twitterbot. X's guide also flags .htaccess rules such as deny from 199.59.156.* and hosts that block X's IP ranges or its network (AS13414). To allow Twitterbot without allowing impostors, verify it the way X describes: a reverse DNS lookup on the requesting IP should return a twitter.com or twttr.com hostname, and a forward lookup of that hostname should return the same IP.
X's guide adds that its crawler "requires the use of TLS v1.1 or greater," and that an incorrect SSL configuration may stop it reaching your site.
Are the tags in the HTML X fetches?
Twitterbot reads the HTML your server sends. Next.js lists Twitterbot among the HTML-limited bots for which it keeps metadata in the <head>, and the comment in its source explains why: such bots "might explicitly check for metadata in the head tag." Tags added later by client-side JavaScript are not a reliable source for any preview crawler.
Confirm the tags are in the raw response:
curl -s -A "Twitterbot/1.0" https://www.example.com/ | grep -io '<meta[^>]*\(twitter\|og\):[^>]*>'
If nothing prints, the tags come from JavaScript. Render them on the server. The general version of this check, for every platform's crawler, is in OG image not showing.
Why does X still show the old card after a fix?
Because X caches it. X said in its 2022 announcement that "cards data continues to be cached for up to 7 days before being refreshed," and its troubleshooting guide says the crawler "re-indexes the Card tag information on your page roughly every seven days." Images are cached by their URL as well, so an image replaced at the same URL can stay stale.
The way to test and refresh:
Paste the link into the post composer on x.com or in the X app. Do not post it. X says "the card preview will render automatically if the URL has appropriate card metadata."
If the preview is old, test a variant of the URL with a harmless query string, such as https://www.example.com/?v=2, which X's guide describes as a way to get a fresh fetch.
For a changed image, give the image a new URL. X's guide suggests appending a parameter, for example og.png?4362984378, "so that the Twitterbot treats the image as a unique URL and re-fetches the image."
Wait out the cache for the original URL. X says there may be "a delay before new metadata is reflected."
Is the Card Validator still useful?
Only for logs. X "removed the preview functionality from the Card Validator" in August 2022, because its previews "were not always aligned with the display of cards" across platforms. The validator page was kept "for submitting brand new domains, and for using the logs to confirm that cards are accessible or recognised," and it can hint the crawler to revisit a URL.
That means the old advice to "check it in the Card Validator" no longer shows you anything. Use the composer for the preview and the validator's log only to confirm X could read the page. X also notes that when the validator says it cannot render a card, "this may not mean that the card is not functional."
The same caching and inspector pattern applies on LinkedIn, whose Post Inspector both shows and refreshes the preview; LinkedIn link preview not working covers it.
Check the page before you post the link
Most card failures sit in the page rather than in the tags. Run the free scan on LaunchScaler with the URL, no account needed. It does not render X's card, but its checks cover what the crawler needs from the page: markup that closes the <head> early and drops the tags below it, content that only exists after JavaScript runs, redirect chains, deprecated TLS versions, and an incomplete or expired certificate chain. Fix those, then paste the link into the composer to confirm the image.
02
Does X use Open Graph tags?
Yes, as fallbacks. X's markup reference maps twitter:title to og:title, twitter:description to og:description, twitter:image to og:image and twitter:image:alt to og:image:alt. Set twitter:card yourself, because it chooses the card type.
03
Is the Twitter Card Validator still working?
The Card Validator's preview was removed in August 2022. X recommends pasting the link into the post composer, where the card preview renders without posting. The validator page was kept for its logs, which show whether X could read the card.
04
How long does X cache a card?
X said in 2022 that card data is cached for up to 7 days before being refreshed. Its troubleshooting guide says images are cached by URL, so adding a query parameter to the image URL makes Twitterbot fetch it again.
05
What image size does a Twitter large image card need?
X's large image card supports a 2:1 aspect ratio, at least 300 x 157 px and at most 4096 x 4096 px, under 5 MB, in JPG, PNG, WEBP or GIF. SVG is not supported. A 1200 x 630 image works and also fits Facebook and LinkedIn.