VASTlint

VAST tag validation in Rust with vastlint-core

Short answer: use vastlint-core if you want VAST validation to run directly inside a Rust service or ad-tech pipeline.

This is the lowest-overhead way to validate VAST XML in production. The same Rust core powers the CLI, web validator, Go binding, and MCP server, but vastlint-coreis the direct library surface for teams building SSPs, DSPs, SSAI systems, and ad servers in Rust.

Why use the Rust crate

  • In-process validation for latency-sensitive infrastructure
  • Zero runtime dependencies
  • Direct access to stable rule IDs, severities, and document paths
  • Best fit when validation belongs in the request path, not in a browser or subprocess

Install

cargo add vastlint-core

Minimal example

use vastlint_core::validate;

let result = validate(vast_xml);

if !result.summary.is_valid() {
    for issue in &result.issues {
        eprintln!("[{}] {} - {}", issue.severity, issue.id, issue.path);
    }
}

Why validate VAST in-process

An invalid VAST tag is an impression that gets billed but never renders: the player loads, the auction clears, the publisher is charged, and the viewer sees a blank slot. At scale that is a steady revenue leak you only learn about from player-side error beacons, too late to do anything about that specific impression.

If you are building the hot path in Rust, you are already optimising for tail latency and deterministic behaviour. A remote validation service undoes both: it adds a network hop per creative and a dependency that can stall or fail the request. vastlint-core has zero runtime dependencies and runs in the same process, so validation is a function call on the order of microseconds, cheap enough to put in front of every creative without touching your latency budget.

Where it lands in an SSP, DSP, or ad server

Rust tends to be the choice for the most latency-sensitive component in the chain: the exchange core, the SSAI packager, or the bidder itself, which is exactly where in-process validation pays off most.

  • SSP / exchange: validate the VAST in each seatbid.bid.adm before you forward the winning bid, and fall through to the next bid if it fails, with no extra round trip to the viewer.
  • DSP / bidder: validate the creative you are about to bid with so you never win an impression the player cannot render.
  • SSAI / ad insertion: gate the stitcher: a creative that fails validation never gets spliced into the manifest, so one bad ad cannot corrupt a stream for every viewer on it.
  • Ad server: validate at trafficking and ingestion so broken tags are rejected before they are ever eligible to serve.

The result type carries stable rule IDs, severities, and document paths, so you can make the accept/reject decision on specific rules (for example, treat HTTPS and missing-impression failures as hard rejects while logging advisories) rather than a single boolean.

When not to use the Rust crate

If you are doing manual QA, the web validator is faster. If you only have a live tag URL, use the tester. If the failure is coming from redirect depth or wrapper handoff, use the inspector.

Related reading