Online ResourcesPrashant Chaudhary

Do Open-Source Video Ad Clients Follow VAST 4.3? An Empirical Study of Player Conformance

Online Resource 4: Google IMA HTML5 SDK, operational setup

Online Resource 4 to "Do Open-Source Video Ad Clients Follow VAST 4.3? An Empirical Study of Player Conformance" (Prashant Chaudhary, October 2026). Google's IMA HTML5 SDK is proprietary and runs in browsers only, so the paper reports it as a comparison in Section 5.1.5, with a short description of how it was pinned and run. This document holds the full operational record behind that section: how the SDK was pinned and archived, the archive manifest (hashes only), how Google telemetry was stubbed (including the ad-traffic-quality hosts), where every request of the reported runs went, the HTTPS server and certificate, the Local Network Access flag, how IMA's own controls were clicked, how the skip API behaved, why Safari did not run IMA, and, for each of the eight IMA findings, the requests the server logged and the errors IMA's public API raised. IMA is reported strictly as a black box: it is graded only from its network requests and the events of its public API, and no verdict, finding or explanation in this document or the paper is taken from the SDK's code (the consistency audit of Online Resource 2, Section 2.3, cites offsets in the archived bridge file; nothing reported rests on them). Paths are relative to the root of the replication repository. The archived Google files are proprietary and are not part of this document or of the public release; this document gives their URLs and hashes, which are in sources/ima-html5/2026-10-16/README.md and index.tsv.

1. What was run

2. Pinning and the archive

Why pin (sources/ima-html5/2026-10-16/README.md): ima3.js is a loader. It loads a versioned bridge frame and fetches a publisher configuration that carries server-assigned experiment state, so live runs can differ from one another. Replaying archived files fixes the SDK version and the configuration.

How it was pinned:

Archive manifest

Source: sources/ima-html5/2026-10-16/index.tsv (11 rows, 9 distinct hashes, which matches the 9 files in files/). Hashes only; no archived content is reproduced here.

Table R4.1. Archive manifest

showing 11 of 11CSV
1https://imasdk.googleapis.com/js/sdkloader/ima3.jsef9c29bc079af27701174c27d25d1b8f4f4333c7e2579bb471c269c0a18e63db200text/javascript; charset=UTF-8
2https://securepubads.g.doubleclick.net/pagead/ima_ppub_config5da8ad7612cba9c31ab4d13841b592c4a2e89f4ba3a867c0b88d1c8703817451200application/json; charset=UTF-8
3https://pagead2.googlesyndication.com/omsdk/releases/live/omweb-v1.js6edb5275ff2227bece0bf3341bdabb6f2f6d8ff1fb31d726d263eb317996f4b3200text/javascript
4https://s0.2mdn.net/instream/video/client.jsd0bffc7261df1454c5e05475cda7d9e6647318dc6c3936767e1252bfe8849c54200text/javascript
5https://imasdk.googleapis.com/js/core/bridge3.794.0_en.htmlf5648dc8113229af71c1b97a81dacfd5f8db46771c78f25fe0437caef4fe1fd0200text/html
6https://pubads.g.doubleclick.net/pagead/managed/dict/m202610150101/ima1e04e0a75b28994312783dbadab17aa57e2d91549a803902e76328dcb137e3dd200text/plain; charset=UTF-8
7https://ep2.adtrafficquality.google/sodar/sodar2.js1fced7b2a471cda6a17da299daf9f375bc9755fc3f00cdf2937f87c81ecdc10e200text/javascript
8https://ep2.adtrafficquality.google/sodar/sodar2/255/runner.htmlc41f41da455986cf9d074c517db41020baf05e060802c11b45cb0a0a24f2a87e200text/html
9https://pagead2.googlesyndication.com/bg/HEjx3T2vFPNzlAOU_OIXv8rutZFOHemhIBBYy52kE84.js1c48f1dd3daf14f373940394fce217bfcaeeb5914e1de9a1201058cb9da413ce200text/javascript
10https://pagead2.googlesyndication.com/omsdk/releases/control/omweb-v1.js6edb5275ff2227bece0bf3341bdabb6f2f6d8ff1fb31d726d263eb317996f4b3200text/javascript
11https://pagead2.googlesyndication.com/omsdk/releases/canary/omweb-v1.js6edb5275ff2227bece0bf3341bdabb6f2f6d8ff1fb31d726d263eb317996f4b3200text/javascript

3. Telemetry stubbing

Source: sources/ima-html5/2026-10-16/README.md; code/harness/browser/run-browser.mjs (TELEMETRY, extRoute).

/^https?:\/\/((pagead2\.googlesyndication\.com|securepubads\.g\.doubleclick\.net|googleads\.g\.doubleclick\.net)\/(pagead\/(gen_204|ping|adview|interaction|conversion)|pcs\/view|activeview)|ep\d\.adtrafficquality\.google\/(generate_204|pagead\/sodar|getconfig\/sodar))/

4. Network containment

Source: sources/ima-html5/2026-10-16/README.md; code/harness/browser/run-browser.mjs (extRoute, TELEMETRY); chromium/summary.json in the archive's reference results and results.jsonl; paper Section 5.1.5 and the Ethics statement.

5. HTTPS server and certificate

Source: paper Section 5.1.5; code/harness/browser/run-browser.mjs (comment before TLS_HOST); code/harness/browser/tls/README.md.

6. Local Network Access flag

Source: code/harness/browser/run-browser.mjs (comment and constant LNA); paper Section 7, internal validity ("a browser security check disabled").

--disable-features=LocalNetworkAccessChecks,BlockInsecurePrivateNetworkRequests,PrivateNetworkAccessSendPreflights,PrivateNetworkAccessRespectPreflightResults

7. Click mechanics

Source: code/harness/browser/run-browser.mjs (vastconfFrameClick, the popup handler); code/harness/browser/ima-adapter.mjs.

8. Skip API behavior

Source: code/harness/browser/ima-adapter.mjs. The paper does not report this observation.

9. Why Safari did not run IMA

Source: results/macos/logs/08b-safari.log and 09-compare.log; paper Section 4.3.

10. Black-box evidence for each IMA finding

The paper reports eight findings for IMA (Appendix B, Table B7: F79 to F86). Each is stated here only through what can be observed from outside: the vector that was sent, the requests the recording server logged, and the events and errors of IMA's public API (the steps field of the stored result). This section gives no explanation of why IMA behaves as it does, because no explanation was taken from the SDK's code, and none is needed for the deviation: each is visible in the request log.

Sources: the Chromium, Firefox and WebKit reference runs on Linux (results.jsonl, fields requests and result.steps; Chromium 141, Firefox 142 and WebKit 26) and the macOS run (results/macos/browser/), and the three probes of the archive's IMA probe results (README.md there has the full request logs). Case ids are those of the stored runs: ch Chromium, fi Firefox, we WebKit, gc Google Chrome. In the request column, doc is a VAST document the server served, t a tracking or error request and media a video file; w0, w1 and so on are the Wrappers of the chain, in the InLine ad. Content-video requests are left out. In the API column, "no AdError" means the ad played from LOADED to ALL_ADS_COMPLETED (or to the harness's stop) without an AD_ERROR event.

Table R4.2. Black-box evidence for each IMA finding

showing 8 of 8CSV
F79W03, w_five (a chain of five Wrappers, then an InLine). Chromium ch0024, Firefox fi0024doc start.xml, w1.xml, w2.xml, w3.xml, w4.xml (five Wrapper documents fetched); then t w4/err?code=302, w3/err?code=302, w2/err?code=302, w1/err?code=302, w0/err?code=302 (the Error URIs of all five). The InLine document inline.xml is never requested; no impression, no mediaAD_ERROR, code 302 (IMA code 302), message "The maximum number of VAST wrappers (4) has been reached."; no ad started. Same in Firefoxnone
F80W17, w_click_wrapper_fallback (two Wrappers that carry ClickTracking and ClickThrough, an InLine that carries neither). Chromium ch0108, Firefox fi0108; same result in the probe run's control ch0001doc start.xml, w1.xml, inline.xml; media ad-10s.webm; t w0/imp, w1/imp, in/imp; t start for in, w1, w0; t firstQuartile for in, w1, w0. After the click, nothing: no clicktracking request for w0, w1 or in, no clickthrough request, and the stored result has no click-through URLLOADED, CONTENT_PAUSE_REQUESTED, IMPRESSION, STARTED, FIRST_QUARTILE, PAUSED (raised during the harness's mouse click on IMA's click element, in IMA's frame), then, after the harness stops the ad, CONTENT_RESUME_REQUESTED and ALL_ADS_COMPLETED; no AdErrorPRB3 (ch0006): an InLine with ClickTracking and no ClickThrough. Same events up to PAUSED after the click; the log ends at t in/firstQuartile; no t in/clicktracking
F81W20, w_allow_multiple_false (a Wrapper with allowMultipleAds="false" whose target holds a pod and a stand-alone ad): Chromium ch0132, Firefox fi0132. W21, w_allow_multiple_default (the same without the attribute): Chromium ch0140, Firefox fi0140.doc start.xml, pod.xml; no t request at all (no Error URI, no impression), no ad mediaAD_ERROR, code 2 (IMA code 2), message "Ad source cannot contain playlist response."; no ad started. Same in Firefoxnone
F82W23, w_fallback_noad (a Wrapper with fallbackOnNoAd="true" whose target holds no ad, plus a second, stand-alone ad s1 in the same document): Chromium ch0252, Firefox fi0252doc start.xml, noad.xml; t noad/err?code=303, w0/err?code=303; no s1/imp, no ad mediaAD_ERROR, code 900 (IMA code 1009), message "The response does not contain any valid ads."; no ad started. Same in Firefoxnone
F83A03, a_verification_js (a Wrapper and an InLine that each carry one unsupported verification with a verificationNotExecuted URL). Chromium ch0324, Firefox fi0324; same result in the probe run's control ch0002doc start.xml, inline.xml; t in/vne?reason=2 (the InLine's report, with reason 2); w0/vne is never requested. The ad then plays to the end (impression, start, quartiles, complete for in and w0).no AdError; LOADED to COMPLETE, then CONTENT_RESUME_REQUESTED and ALL_ADS_COMPLETEDPRB1 (ch0004): the Wrapper carries one unsupported verification, the InLine none: t w0/vne?reason=2 is requested. PRB2 (ch0005): the InLine carries two: t in/vneA?reason=2 is requested, in/vneB never. In A03 both levels carry a vendor and only the InLine's is reported; the probes show the Wrapper's is reported when the InLine has none, and one report per ad
F84A05, a_verification_404 (an InLine whose OMID verification resource answers 404). Chromium ch0332, Firefox fi0332; control ch0003js in/verif-js?status=404 [404] (the resource was fetched and the server answered 404); the ad plays to the end (imp, start, quartiles, complete for in); in/vne is never requestedno AdError; LOADED to COMPLETE, then CONTENT_RESUME_REQUESTED and ALL_ADS_COMPLETEDnone
F85I01, i_icon (an InLine with one icon, no offset). Chromium ch0396, Firefox fi0396, WebKit we0396; macOS: the same vector in Chromium, Chrome, Firefox and WebKitChromium: doc start.xml; t in/icon-view at 2927020 ms, in/icon-img, in/imp, in/start at 2927142 ms (view 122 ms before start). Firefox: in/icon-view 88 ms before in/start. WebKit (Linux): in/icon-view 367 ms before in/start. Repeated runs, 20 per Linux engine, the icon cell alone: the view always precedes start, by 36 to 68 ms in Chromium (beyond the 50 ms tolerance in 6 of 20), 54 to 111 ms in Firefox and 165 to 237 ms in WebKit (beyond it in all). macOS run: the view precedes start by 9 to 27 ms (within the tolerance); 10 repeats per browser on macOS: 11 to 12 ms in Chromium, 10 to 13 ms in Chrome and 13 to 50 ms in Firefox (never beyond), 51 to 58 ms in WebKit (beyond in all 10)no AdError; LOADED to COMPLETEnone. For comparison, I03 (i_icon_timed, an icon with a 1 s offset) conforms in all three Linux engines: the view is requested 1297, 1153 and 929 ms after start
F86W11, w_malformed (a Wrapper whose target is not well-formed XML). Firefox fi0072 (the finding). For comparison: Chromium ch0072, WebKit we0072 (results.jsonl of the second Linux WebKit run in the archive), Google Chrome gc0289 (results/macos/browser/chrome/results.jsonl)Firefox: doc start.xml, bad.xml; t w0/err?code=303. Chromium, WebKit, Chrome: doc start.xml, bad.xml; t w0/err?code=100Firefox: AD_ERROR, code 303 (IMA code 303), message "No Ads VAST response after one or more Wrappers". Chromium, WebKit, Chrome: AD_ERROR, code 100 (IMA code 100), message "VAST response was malformed and could not be parsed."none

Reading the table: