VideoObject Schema Valid but No Video Rich Result

Your VideoObject JSON-LD passes Rich Results Test but Search Console shows no indexed video. The real cause is usually thumbnail, embed URL, or video prominence — here is how to find which.

You embedded a video (YouTube, Vimeo, self-hosted MP4) on an article page and added a VideoObject JSON-LD block. Rich Results Test reports “Valid” and shows the parsed preview. Weeks pass. The Search Console Video indexing report still shows the page as “No video indexed”, or the page is indexed but with no video appearance, and your URL never shows in Google’s video tab.

Fastest fix first: valid schema is necessary but not sufficient. Open the Video indexing report at search.google.com/search-console/video-index, click the affected page, and read the exact reason Google gives. Nine times out of ten it is one of three things: (1) the video isn’t on a “watch page” / Google can’t determine its position and size, (2) the thumbnail is unreachable or the wrong format, or (3) embedUrl points at a wrapper page instead of the player. The report names the specific issue — match it to the sections below.

As of June 2026, Google still requires four things beyond valid syntax: a reachable thumbnail in a supported format, a contentUrl or embedUrl that resolves to an actual video player or file, an ISO 8601 uploadDate, and a publicly crawlable video that is the prominent content on the page. This article walks the six failure modes with the exact Search Console issue names.

Identify which case you are in (10 seconds)

Open the Video indexing report, click the URL, and look at the issue name Google reports. Match it here:

Search Console issue nameReal causeSection
Video isn't on a watch pageVideo is decorative / not the main content of the page1
Cannot determine video position and sizePlayer loads off-screen, too small, too tall, or needs a click1
No thumbnail URL provided / Invalid thumbnailthumbnailUrl missing, gated, or wrong format2
Thumbnail could not be reached / Thumbnail blocked by robots.txtGooglebot can’t fetch the image2
Video not found on host serviceembedUrl / contentUrl points at HTML, or video is private3, 4
Rich Results Test “Valid” but report shows nothing for weeksPage not crawled yet, or uploadDate not ISO 86015, 6

If the report shows the page as fully indexed for video but the SERP thumbnail is missing, that is almost always the thumbnail (section 2).

Common causes, ranked by hit rate

1. Video prominence — “not on a watch page” or “can’t determine position and size”

This is the single most common reason embedded videos never get indexed, and it has nothing to do with your JSON-LD. Google only indexes a video when it is the prominent content on the page, on what Google calls a “watch page” — a page whose main purpose is to show that single video.

Two Search Console issues map to this:

  • Video isn't on a watch page — Google decided the video is decorative (a small inline clip surrounded by article text). A page that is 90% prose with a video embedded mid-article often trips this.
  • Cannot determine video position and size — the player isn’t visible at a real size and position when the page first loads. This fires when the player is lazy-loaded behind a click-to-play poster, hidden in a tab/accordion, or pushed below the fold.

Google documents concrete thresholds for the prominence sub-issues. As of June 2026:

Sub-issueThresholdFix
Video outside the viewportPlayer not in the renderable area on loadReposition so the whole player is visible when the page loads
Video too smallSmaller than 140px in width or height, or less than a third of page widthMake the player larger than 140px and at least a third of the page width
Video too tallTaller than 1080pxReduce player height below 1080px

Fix: render the real player (not a click-to-play placeholder) at a real size, above the fold, on a page where the video is the main point. If your videos are genuinely supporting content inside long articles, accept that those pages may rank for the article but not earn a standalone video result — that is expected, not a bug.

2. Missing, unreachable, or wrong-format thumbnailUrl

thumbnailUrl is a required field. If Google can neither fetch your thumbnail nor generate one, the video cannot be indexed at all. The exact rules (Google video docs, current as of June 2026):

  • Supported formats: BMP, GIF, JPEG, PNG, WebP, SVG, AVIF. A .jpg served with the wrong Content-Type, or an unsupported format, triggers Invalid thumbnail / Unsupported thumbnail format.
  • Minimum size: 60x30 pixels. There is no hard 1200x720 requirement, but a small thumbnail will rarely render in the SERP — aim for 1280x720 (16:9) or larger for an actual visible thumbnail.
  • Must be reachable: served over a stable HTTPS URL, not blocked by robots.txt, no login required. A gated image yields Thumbnail could not be reached or Thumbnail blocked by robots.txt.
  • Transparency: at least 80% of pixels must have an alpha value above 250 (i.e. mostly opaque). A heavily transparent PNG triggers Thumbnail is transparent.
{
  "@type": "VideoObject",
  "thumbnailUrl": [
    "https://yourdomain.com/videos/foo-thumb-1280x720.jpg",
    "https://yourdomain.com/videos/foo-thumb-1920x1080.jpg"
  ]
}

You can pass an array of thumbnail URLs; Google picks the best one. Use one stable, unique URL per video.

How to spot it:

curl -A "Googlebot/2.1 (+http://www.google.com/bot.html)" -I "https://yourdomain.com/videos/foo-thumb.jpg"
# Expect: HTTP/2 200 and a content-type of image/jpeg (or png/webp/avif)
identify "https://yourdomain.com/videos/foo-thumb.jpg"   # ImageMagick — confirms dimensions and format

A 403/401/302 status means the thumbnail is gated. A content-type of text/html means the URL returns a page, not an image.

3. contentUrl or embedUrl points to a page, not a video

contentUrl must be a direct URL to a video file (mp4, webm, mov) — not the URL of the article page that contains a <video> tag. embedUrl must be the player iframe URL, not the article page either.

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "contentUrl": "https://yourdomain.com/articles/how-to-foo/",
  "embedUrl": "https://yourdomain.com/articles/how-to-foo/"
}

Both URLs above are wrong — they point at the wrapping article page. Googlebot fetches them, gets HTML back, finds no video file or player, and reports Video not found on host service.

Fix: link contentUrl directly to the file and embedUrl to the player:

{
  "@type": "VideoObject",
  "contentUrl": "https://cdn.yourdomain.com/videos/how-to-foo.mp4",
  "embedUrl": "https://www.youtube.com/embed/VIDEO_ID"
}

For YouTube, embedUrl is https://www.youtube.com/embed/VIDEO_ID — note /embed/, not /watch?v=. For Vimeo it is https://player.vimeo.com/video/VIDEO_ID. Google recommends supplying contentUrl when you can; it is the most reliable way for Google to fetch the file. If only embedUrl is available (YouTube/Vimeo embeds), that is fine on its own.

4. Video gated — login wall, paywall, geo-block, or private

If Googlebot cannot fetch the video file (or its embed page), it cannot verify the video exists, and you get Video not found on host service. Paywalled content, Vimeo private videos, and region-locked content are excluded from video results.

How to spot it:

curl -A "Googlebot/2.1" -I "https://www.youtube.com/embed/VIDEO_ID"
# Expect 200; a 302-to-login or 401 means gated

For YouTube unlisted videos, VideoObject still works as long as embedUrl is the public embed URL. Truly private videos cannot earn video results.

Fix: for paywalled video, use paywalled content markup (isAccessibleForFree: false plus hasPart with cssSelector). Google has a separate compliance path for paywalled video.

5. uploadDate not in ISO 8601 format

uploadDate is required and must be ISO 8601, ideally with a timezone. "2026-05-19" is accepted but date-only; "2026-05-19T14:30:00-07:00" (Google’s own documented example format) is what to emit.

{
  "@type": "VideoObject",
  "uploadDate": "2026-05-19T14:30:00-07:00"
}

Common mistake: emitting "5/19/2026" (US locale) or a localized string with non-ASCII separators (for example a date rendered with Chinese or Japanese era characters). Both fail validation.

6. Multiple VideoObject blocks on one page conflict

A page with both a hero video and an inline embedded video may emit two VideoObject blocks. If both share the same name or contentUrl, Google treats it as duplicate / ambiguous and may pick neither.

Fix: one canonical VideoObject per page representing the primary video. If you genuinely have multiple distinct videos on one page, give each a unique name and contentUrl, and consider whether each deserves its own dedicated URL — remember Google indexes one prominent video per page (see section 1).

A copy-ready VideoObject template

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to set up a self-hosted server in 10 minutes",
  "description": "Step-by-step walkthrough covering hardware selection, OS install, and SSH hardening.",
  "thumbnailUrl": [
    "https://yourdomain.com/videos/server-setup-thumb-1280x720.jpg",
    "https://yourdomain.com/videos/server-setup-thumb-1920x1080.jpg"
  ],
  "uploadDate": "2026-05-19T14:30:00-07:00",
  "duration": "PT10M30S",
  "contentUrl": "https://cdn.yourdomain.com/videos/server-setup.mp4",
  "embedUrl": "https://www.youtube.com/embed/VIDEO_ID",
  "publisher": {
    "@type": "Organization",
    "name": "Site name",
    "logo": {
      "@type": "ImageObject",
      "url": "https://yourdomain.com/logo.png"
    }
  },
  "potentialAction": {
    "@type": "SeekToAction",
    "target": "https://yourdomain.com/videos/server-setup#t={seek_to_second_number}",
    "startOffset-input": "required name=seek_to_second_number"
  }
}

duration uses ISO 8601 duration format: PT10M30S = 10 minutes 30 seconds, PT1H5M = 1 hour 5 minutes. The SeekToAction block enables Key Moments and is optional.

Shortest fix path

In hit-rate order:

  1. Read the exact issue name in the Video indexing report (search.google.com/search-console/video-index) — this tells you which fix you need instead of guessing.
  2. Make the player prominent: real player, above the fold, larger than 140px, on a watch-style page — fixes the most “No video indexed” cases.
  3. Make embedUrl the actual player URL (/embed/VIDEO_ID for YouTube, /video/VIDEO_ID for Vimeo).
  4. Verify Googlebot can fetch the thumbnail with curl -A "Googlebot/2.1"; serve a supported format at 1280x720+.
  5. Convert uploadDate to ISO 8601 with timezone.
  6. One canonical VideoObject per page.

How to confirm it’s fixed

  1. Run the URL through Rich Results Test — confirm VideoObject parses with no errors and the thumbnail preview renders.
  2. In Search Console, use URL Inspection → Test Live URL → View crawled page, and confirm the rendered HTML contains your player at a real size above the fold.
  3. Back in the Video indexing report, click the URL and confirm the issue moved to Indexed. Re-crawl can take days to weeks; use “Validate fix” to queue it.
  4. Search site:yourdomain.com/your-page after indexing and check the video tab for a thumbnail.

Prevention

  • Build VideoObject emission into a shared video-embed component so every embedded video automatically gets schema. Hand-written per-page JSON-LD drifts.
  • Validate required fields at build time: fail the build if name, description, thumbnailUrl, uploadDate, or one of contentUrl / embedUrl is missing.
  • Generate thumbnails from a 1920x1080 source; downscale to 1280x720 for the schema array. Keep one stable URL per video.
  • Render the player at a real size above the fold on pages where the video is the point — do not hide it behind click-to-play if you want indexing.
  • Watch the Video indexing report weekly. A sudden drop usually means a template regression.

FAQ

Q: Does embedding a YouTube iframe automatically generate VideoObject for my page? A: No. YouTube emits VideoObject on its watch page (youtube.com/watch?v=...), not on your page. When you embed via iframe, your page has no schema unless you add it manually.

Q: What are the required fields for VideoObject? A: name, description, thumbnailUrl, uploadDate, and one of contentUrl or embedUrl. Providing both contentUrl and embedUrl is recommended for maximum compatibility.

Q: Rich Results Test says “Valid” but weeks later there’s still no video listing. Why? A: Validation only checks schema syntax. Indexing also requires Googlebot to crawl the embed/content URL, confirm a video exists, and judge the video prominent on the page. Open the Video indexing report and read the exact issue — most “No video indexed” cases are the prominence rules in section 1, not your JSON-LD.

Q: What thumbnail size does Google actually require? A: The hard minimum is 60x30 pixels in BMP, GIF, JPEG, PNG, WebP, SVG, or AVIF. For an actual visible SERP thumbnail, use 1280x720 (16:9) or larger. The thumbnail must be reachable by Googlebot, not blocked by robots.txt, and at least 80% opaque.

Q: My YouTube video appears in Google’s video tab from the YouTube URL but not from my page. A: Expected. The YouTube watch page is the canonical for that video. Your page can also rank, but only if the embed is set up correctly and your page adds unique value beyond the embed.

Q: Should I use contentUrl or embedUrl? A: Both if possible. Google prefers contentUrl (the direct file) because it can fetch the video itself; embedUrl is the player users see. Self-hosted: set both. YouTube/Vimeo embeds: only embedUrl is available, which is fine.

Q: My video is on a paywalled article. Can I still get video results? A: Yes, via paywalled content markup (isAccessibleForFree: false). Google has a separate compliance path — register your site and follow the guidelines.

Tags: #SEO #Troubleshooting #Debug #Structured data #Video schema #JSON-LD