VAST 4.2 tag testing — a complete walkthrough
Video ad tags have more failure modes than display tags, and VAST 4.2 layered on new requirements on top of the old ones. Here's how to test a VAST tag end-to-end.
What VAST 4.2 actually changed
VAST 4.2 is an IAB-ratified spec released October 2019 and widely adopted by 2023. The most important changes vs 3.0:
-
Separated creative from serving — the
<UniversalAdId>element carries creative identity across wrappers -
MediaFile code-agnostic — you can now deliver the creative via
<Mezzanine>separately from the streamable<MediaFile>copies -
Interactive creative files —
<InteractiveCreativeFile>element for VPAID replacement via OMID/SIMID -
Verification — standard
<AdVerifications>element with<Verification>children for OMID / DV / IAS -
Error tracking — richer
<Error>pixel with macro-substituted error codes - Icons — formalized "AdChoices" icon element for privacy-regulation compliance
The eight things every VAST test must check
1. VAST version declaration
<VAST version="4.2">...</VAST>
If the tag declares 4.2 but uses only VAST 2.0 elements, many video players will render it
as 2.0 and silently drop the new features. If the tag declares 3.0 but uses 4.x elements
(like <AdVerifications>), older players will silently ignore them.
Match the version to the content.
2. Wrapper chain resolution
Most VAST tags are wrappers — they return a <Wrapper> with a
<VASTAdTagURI> pointing at another server. You follow the chain until
you hit an <InLine> with the real creative.
Problems to catch:
- Infinite loops — A points at B which points at A
- Excessive depth — industry norm is ≤3 hops; >5 is almost always a mistake
- Failed hops — 404, 5xx, or timeout at any wrapper terminates the ad request with no creative
- Missing macros — the upstream server substitutes macros (cachebuster, content ID, etc.) that aren't in your outer wrapper's URL
3. MediaFile availability
Every <MediaFile> URL should:
- Return HTTP 200 (fetch +
Content-Lengthcheck) -
Have the declared
type=MIME match the actual responseContent-Type - Be served over HTTPS
-
Match declared
width/height/bitrate(download first KB, probe with ffprobe)
<MediaFile
delivery="progressive"
type="video/mp4"
bitrate="2000"
width="1280"
height="720"
codec="avc1.4D401F">
https://cdn.example.com/creative/ad-720p.mp4
</MediaFile>
4. Tracking pixel reachability
VAST tags fire many different tracking pixels. Each must be reachable and served over HTTPS:
| Event | When it fires | Required? |
|---|---|---|
| impression | ad begins rendering | Yes |
| start | first frame played | Yes |
| firstQuartile | 25% played | Optional |
| midpoint | 50% played | Optional |
| thirdQuartile | 75% played | Optional |
| complete | 100% played | Yes |
| clickTracking | user clicks the ad | Yes (if clickable) |
| error | playback fails | Recommended |
5. Click-through URL
The <ClickThrough> element must contain a valid landing URL. If it's a
redirect, follow the chain and verify SSL on every hop.
6. Companion ads
VAST supports <CompanionAds> that render alongside the video (typically
static banners). Each companion has:
<StaticResource>— HTTPS image URL<IFrameResource>— HTTPS iframe source<HTMLResource>— inline HTML (rarely a good idea)
7. OMID / IAB verification
VAST 4.x defines a standard verification block:
<AdVerifications>
<Verification vendor="doubleverify.com">
<JavaScriptResource apiFramework="omid">
https://cdn.doubleverify.com/omid.js
</JavaScriptResource>
<TrackingEvents>...</TrackingEvents>
<VerificationParameters>...</VerificationParameters>
</Verification>
</AdVerifications>
Check that every JavaScriptResource is HTTPS and
apiFramework="omid" is declared (VPAID is deprecated as of VAST 4.2).
8. Duration declaration
The <Duration> element declares creative length
(HH:MM:SS). If it doesn't match the actual MP4 duration, quartile pixels will
fire at the wrong offsets and analytics will be wrong.
The VAST QA checklist
- Does the VAST XML parse without errors?
- Is the declared
versionconsistent with the elements used? - Does every wrapper resolve in ≤3 hops with no loops?
- Does every MediaFile URL return 200 + match declared dimensions + bitrate?
- Does every tracking pixel return 200 + use HTTPS?
- Does the ClickThrough URL resolve through the redirect chain on HTTPS?
- Are companion ads present + valid (if expected)?
- Is OMID verification present + HTTPS (if the publisher requires it)?
- Does the declared duration match the actual MP4?
- Does the tag complete within 30 seconds of the initial ad request?
Paste a VAST URL or VAST XML to run every check above.
Run a VAST scan →Common VAST 4.2 errors I see
-
Missing
UniversalAdId— breaks creative ID propagation through wrappers; most DSPs silently drop the creative -
MediaFile
deliverymismatch — declaredprogressivebut served via HLS chunks - OMID + VPAID both declared — should be OMID only in VAST 4.2; dual-declaration causes player conflicts
-
Tracking pixel macros unsubstituted —
[TIMESTAMP]or[CACHEBUSTER]left literal -
HTTPS
MediaFilebut HTTPIcons— mixed content on the AdChoices icon breaks the entire ad in some players -
Companion without
width/height— companion slot can't be allocated, companion doesn't render -
Error pixel with macros that never substitute — you get data with
[ERRORCODE]literal in your logs
CTV vs mobile-web vs desktop
A VAST tag that passes on desktop may fail on CTV. Connected TV players have stricter requirements:
- Codec support — CTV often requires H.264 baseline/main profile; high profile or H.265 may not decode
- MediaFile dimensions — many CTV platforms require 1920×1080 or higher; 720p may be rejected
- Bitrate ceiling — above 4 Mbps stalls some CTV devices
- No clickability — ClickThrough has no effect; verify this doesn't cause error pixel fires
- OMID only — VPAID doesn't work on CTV; if you ship VPAID to CTV inventory it won't play
For CTV tags, test against a CTV-aware validator that handles the stricter rules. Generic VAST validators will pass tags that won't play on an actual TV.