Browse the help center

Diagnose video ad playback failures (VAST errors)

Reproduce a silent video failure with the placement's VAST tag, read what Epom actually returns on a no-ad, and map common player error codes to the Epom setting that caused them.

Troubleshooting network manager Account → Publishers → site → zone → placement (Video) → Ad tags & API → VAST tags

A video slot stays blank, the player skips straight to content, or you get a bare “ad error” with no detail. Video players swallow VAST errors — they rarely tell you why, they just move on. This page turns that silence into a diagnosis: reproduce the failure with the placement’s own VAST tag, read what Epom actually returned, and map the player’s error code (if you can get one) to the Epom setting behind it.

This is a video-specific companion to Tags and preview problems, which has the one-line version of this symptom.

First: what Epom returns when nothing serves

Knowing Epom’s actual responses stops you chasing a player bug that is really a “no ad matched”. On a video (VAST) request Epom returns one of:

SituationEpom returnsWhat the player does
A banner matchedA full <VAST> with the creative’s media/wrapperPlays the ad
A request reached a real placement but no banner matchedA <VAST> with an <Error> element carrying a tracking beacon URL — Epom puts no error code of its own in it, only an [ERRORCODE] slot for the player to fillFires the beacon, then reports its own no-ads error (commonly 303)
The request had no valid placement (bad key, wrong URL)An empty <VAST … /> with no <Ad>, at the version the tag asked for (2.0 when the request itself could not be read)Reports an empty/parse error

The key takeaway: the error code you see in the player is the player’s, not Epom’s. Epom’s no-ad response is a valid VAST document whose <Error> fires a beacon so the no-fill is counted; the player then decides how to surface it. So a “303 No Ads” almost always means Epom found the placement but had nothing to serve — a selection problem, not a tag problem. Work My ad is not serving in that case.

Step 1 — reproduce with the placement’s VAST tag

Don’t debug on the live player first. Get a clean signal from the tag itself.

  1. Open the video placement → the Ad tags & API card → the VAST tags tab. If your network has more than one ad-serving domain, pick the Domain on the card’s Settings tab first.

  2. Pick your player’s spec in the VAST version picker (2.0, 3.0, 4.0, 4.1, 4.2 or 4.3) and copy the VAST tag URL — or copy the VPAID tag or VMAP tag URL, which do not follow the picker. The version rides in the tag’s vastv parameter where it is visible — on networks that serve encrypted tag URLs it is inside the ciphertext, so read it off the response instead (below).

  3. Paste it into a VAST validator/inspector (your player vendor’s, or any standalone VAST tester). This shows the raw XML Epom returns for that exact tag, with none of the player’s error-swallowing.

    The AI assistant can do this for you: ask it to check the tag URL and it summarises the response — VAST version, each ad as InLine or Wrapper (following wrappers up to three levels), media files with type, size, bitrate and VPAID, and tracking counts — or says there was no ad. Its request comes from a datacenter with a stock desktop, iPhone or Android browser, so a no-ad there can simply be targeting (country, device, IP, frequency) keeping that request out; confirm from a real device before blaming the tag.

What you learn immediately:

  • Empty <VAST/> or a <VAST>…<Error> with only a beacon → no ad matched (or no valid placement). Go to Step 2.
  • A full <VAST> with a MediaFile or VASTAdTagURI → Epom is serving; the failure is playback-side (media, wrapper, VPAID, mime). Go to Step 3.

Corner case: check which VAST version the response actually declares. Read it off the root element — <VAST version="…"> — rather than off the tag URL: the URL’s vastv= parameter says the same thing, but on networks that serve encrypted tag URLs the whole query is wrapped into ciphertext and no vastv is visible even though the tag carries one. A hand-edited or truncated URL that genuinely has no vastv (or an unknown one) is answered with VAST 2.0 for a no-ad response, which can be rejected by a player that expects 4.x features. The picker defaults to 4.2. If the tag also has to be viewability-measured, it must be 4.1 or higher and play in an Open Measurement–capable player — see Video placements.

Step 2: no ad matched, selection side

The tag returns empty or an <Error>-only VAST. Epom reached the placement but had no creative. Check, most common first:

  1. No linked, active video banner. A video placement needs a linked banner of a video type (Local Video, External Video, Third Party VAST/VPAID Tag URL, VPAID Framework, Advanced Local Video(s)) that is active, with an active campaign in valid dates/budget. See Video banners.
  2. The banner’s In-Stream video type is not what the request asks for. The server keeps only banners whose In-Stream video type (Linear / Non-linear) matches the types the tag asks for — a plain VAST tag asks for both, linear first — and drops the rest, which the player sees as a no-ad. This is a selection-side cause, not a player one.
  3. An uploaded video misses the site’s Video creative requirements. The file stays linked but is not served on that site; the placement’s linked-banners tree marks it Not served. See Check video creatives against a publisher’s spec.
  4. Targeting / pre-targeting rejected the request. Country, device, time-range and other rules apply to video exactly as to display. Reproduce with the standalone preview’s IP override to test another geo. Behind a server-side ad insertion stitcher the rules see the viewer details the stitcher forwards; one that forwards none shows the rules its own data-centre address (see Serving behind SSAI).
  5. Capping or limits exhausted. A frequency cap or a spent budget/impression limit removes the only candidate.
  6. RTB-only demand that didn’t bid. If the placement relies on programmatic video, an empty response is a no-bid, not a bug.
  7. A pod that comes back shorter than you asked for can be Competitive separation in a pod passing over a creative that clashes with one already in the break — see Keeping competitors apart in a pod.
  8. The site, zone or placement is switched off. A VAST tag of a paused placement — or of a placement whose site or zone is paused — answers with no ad even though the banner side is fine. Supply needs placement and zone and site on.
  9. A limit on the placement or site. A Total limit that is reached switches the entity off, and it stays off after you raise the limit — switch it on again yourself (see Limits).
  10. Site- or zone-level pretargeting. A country rule on the site (or zone) applies to every placement under it — a “VAST returns an error everywhere except from one country” report is usually this. Check the site’s targeting, not only the campaign’s.

Is an empty VAST normal? (fill rate)

Yes, for part of the traffic. Every request the placement cannot fill — no eligible banner, a cap, a no-bid — is answered with the no-ad VAST above, and the player shows its no-ads error for it. A placement filling 15% of its requests answers 85% of them empty by design. Read the share from a General report grouped by placement: Impressions ÷ Requests. Only a fill of zero, or a sudden drop against the same period before, points to a set-up problem — then work the list above. See also Low fill rate.

Confirm it is selection, not tag, in analytics: a General report grouped by placement shows non-zero Requests with zero Impressions for a no-fill. Full checklist: My ad is not serving.

Step 3: Epom served but playback fails

The validator shows real creative markup, yet the live player still fails. The cause is now in the creative or the player, not selection:

  • Third-party VPAID tag in a non-VPAID player. A VAST tag that contains a JavaScriptResource / VPAID script needs a VPAID-capable player. A plain VAST player renders nothing for it and usually reports a linearity or media error. Confirm the banner is a Third Party VAST/VPAID Tag URL type and that your player supports VPAID.
  • Wrapper that never resolves. A VAST Tag banner is a wrapper — the player must follow VASTAdTagURI to the real ad. If the wrapped tag is slow, unreachable, or exceeds the player’s wrapper-depth limit, the player times out. On the banner, the VAST 4.0 Wrapper properties (Follow additional wrappers, Allow multiple ads, Fallback on no ads) control this chain — see Video banners. The depth and time limits themselves are the player’s, not settings on the banner.
  • Media-file mime/codec the player can’t decode. For Local/External/Advanced Video, the player needs a MediaFile whose type (mime) and codec it supports. An MP4-only player fed a WebM rendition, or a mismatched declared mime, fails silently. Check the <MediaFile type="…"> in the validator against your player’s supported formats.
  • Ad-pod expectations. If the placement returns a pod (Return (ads in pod) > 1) but the player requested a single ad, or the pod exceeds Max. pod duration, playback can partially fail. Match the placement’s pod settings to what the player asks for.
  • Skip settings the player enforces differently. The placement’s Show skip ad button / Show after and the banner’s Show skip button after feed the VAST; a player with its own skip policy may override or conflict with them.

The skip button (skipoffset) is missing from the VAST

Epom writes skipoffset on the <Linear> element only for creatives it serves inline — Local Video, External Video, Advanced Local Videos and VPAID Framework banners — from the banner’s Show skip button after (seconds) — or, when the banner has none, the placement’s skip settings — and never in a VAST 2.0 response, which has no such attribute. A Third Party VAST/VPAID Tag URL banner is a wrapper: the VAST specification has no skip offset on a wrapper, so the field on such a banner has no effect. The skip offset has to be in the partner’s own inline VAST, and the player then shows it.

Pre-roll, mid-roll or post-roll — do I need different VAST tags?

No. A VAST tag does not know where in the content it plays — the player decides when to call it (before, during or after the video). The same placement’s tag can serve pre-roll and mid-roll. If you want the breaks counted separately in reports, use a placement per break (or pass a different channel in each call). A VMAP tag is the exception that describes breaks itself; its Max pre-rolls is set on the video placement — see Video placements.

The ad plays as a separate video on the page, not inside my player

The publisher put the Video Player tag on the page. That tab is a ready-made demo player that renders the placement on its own — it is not a pre-roll for an existing player. For your own player, give it the VAST tag URL (Ad Tags & API → VAST Tags) as its ad tag. The display banner code of another placement is not a VAST tag either; only the video placement’s VAST tag URL returns VAST.

Clicks differ between two players on the same VAST tag

The player decides what is clickable: one player makes the whole video area a link, another shows only a call-to-action button. Epom counts a click when the player opens the VAST’s ClickThrough link (or fires its ClickTracking), so the same tag reports more clicks in the player with the bigger click area. There is no ClickThrough at all when the video banner has no landing URL.

Reading player error codes (Epom-scoped)

Players report IAB VAST error codes. You don’t need the whole dictionary — these are the ones that map to an Epom-side setting or state:

Player code (family)Usually meansWhere to look in Epom
303 No ads after wrapper(s)Epom returned a no-ad <Error> VASTSelection — Step 2
300–302 Wrapper error, timeout or depth limitA VAST Tag banner’s wrapped tag is slow or unreachableBanner VAST 4.0 Wrapper properties, the wrapped tag itself
901 VPAID error / unsupportedVPAID creative in a non-VPAID playerBanner type (VAST/VPAID Tag or VPAID Framework), player capability
400–405 Media-file errorNo playable MediaFile, or a codec/mime the player cannot decodeBanner media files, mime types
201 Video player expecting different linearityThe creative is linear and the player wants non-linear, or the reverseBanner In-Stream video type (Linear / Non-linear)
100 XML parse errorEmpty or malformed response reaching the playerUsually the empty <VAST/> case — bad placement key or hand-edited tag
900 Undefined errorThe player failed and had no more specific code for itWork the checklist in What does VAST error 900 mean?

Note: these ranges are the standard IAB families, but the exact code a player emits varies by player. Treat the code as a pointer to the Epom area, then confirm from the raw XML in Step 1 — the XML is authoritative, the player’s code is a hint.

What does VAST error 900 (Undefined error) mean?

900 is the IAB VAST specification’s “Undefined Error” — the code a video player reports when playback failed and it cannot name a more specific reason. Epom never produces it: every <Error> URL Epom writes (on a served ad, on a wrapper and on the no-ad response) ends in ec=[ERRORCODE], and it is the player that replaces [ERRORCODE] with 900 or any other code. Google IMA in particular folds many different failures into 900 — a VPAID creative that fails, a media file it cannot use, a timeout, a request the browser blocked. So a 900 says “the player gave up”, not where; it needs the same diagnosis as any silent failure.

Check, in this order:

  1. Does Epom serve at all? Open the placement’s VAST tag in the browser (Step 1). An <Error> with no <Ad> is a no-fill — work Step 2, the 900 is a consequence.
  2. Does the media file open, and does it suit the player? Copy the <MediaFile> URL into a browser tab — it must play over https. Its type must be a format the player decodes (an MP4-only player cannot use WebM), and its size and bitrate must be reasonable for the connection (see How heavy should a banner or video be?).
  3. Is it VPAID? A MediaFile of type application/javascript (or a VPAID Framework banner) needs a player with VPAID enabled; Google IMA needs VPAID mode switched on by the publisher. A VPAID script that throws inside the player is also reported as a generic failure.
  4. How deep is the wrapper chain? A Third Party VAST/VPAID Tag URL banner is a wrapper; if the partner’s tag wraps again, every hop costs time and each player stops after its own fixed number of hops. Open the partner’s tag yourself and follow it to the inline ad.
  5. Is anything blocked by the browser? Mixed http content on an https page, and a media file or VAST hosted on a server that does not allow cross-origin requests (CORS), fail in the player with no detail. Open the browser console and the Network tab on the publisher’s page, play the ad, and look for red requests and CORS errors.
  6. What does the player itself say? IMA, JW Player and Video.js write the underlying error to the console in debug mode; that message is more precise than the 900 the VAST pixel gets.

Where Epom sees the code: when a player fires the <Error> pixel, the code it filled in is written to the ad server’s troubleshooting log (“Player reported VAST error code 900”) while a capture is running — your network administrator creates a time-boxed task under Admin → Audit & diagnostics → Troubleshooting log tasks and downloads the logs afterwards (see Capture ad requests with a troubleshooting log task). The code is not a column in the reports.

Did the impression fire?

When a video ad does play, verify tracking is landing rather than assuming it from the visible ad:

  • The placement’s VAST tracking card lets you enable playback events (start, quartiles, complete, skip, viewability). Enabled events appear in the VAST response as tracking URLs and are recorded when the player fires them — see Video placements.
  • In analytics, compare Requests → Impressions first. Requests without impressions = no-fill (Step 2). For playback, group a General report by Conversion action (or Attribution type): the quartile, complete and viewability events are recorded as system conversions, which no longer count in the Conversions column. Impressions without start/quartile events = the player loaded the ad but playback didn’t progress (Step 3 territory — media or player issue).
  • A ticked event can be missing from the XML by design. Event names differ by VAST version and Epom leaves out what a version does not define: Ad loaded appears only from 4.1, Exit fullscreen from 3.0, and the linear-video Expand / Collapse are omitted from 4.x (see Video banners). If an enabled event is absent, check the version of the tag first.
  • OpenRTB video banners never get Epom’s VAST tracking card — their events come from the bid’s own markup, so absent Epom-side events there is expected, not a bug (see OpenRTB (DSP) banners).

Corner cases and gotchas

Corner case: Epom’s no-ad response is a valid VAST document, not an HTTP error. The request returns 200 text/xml with an <Error> beacon inside. A player that only checks the HTTP status will think the call “succeeded” and then fail on the empty ad — look at the body, not the status code.

Corner case: in a VAST 2.0 no-ad response Epom appends &force_fail=true to the beacon (inside <Ad><InLine><Error>, because 2.0 has no document-level <Error>). This is expected in the raw XML of a no-ad response — it is not evidence of a forced failure of your creative.

Corner case: a wrapped third-party VAST that itself returns no ad produces a 303 at the player even though Epom served a perfectly valid wrapper. The chain failed downstream of Epom — test the wrapped tag URL directly to confirm.

When you escalate

Give your network administrator: the placement ID, the VAST tag URL you tested and its version, the raw XML the validator showed (or “empty”), the player and its error code, and the time window + reporting time zone. Your network administrator can additionally check gates you can’t see (consent enforcement, bot and IP filtering, DSP creative-scan verdicts), and Epom support the ad-server snapshot state.

Related pages

Please disable Adblock
Are you using adblock? Disable it and reload the page to proceed to the destination page.

A registration has already been submitted from this page. Please try again in 10 minutes.