Generated banner for AWS Media Services
Generated logo for AWS Media Services

AWS Media Services

AWSOfficialPublished by AWS

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

Designs, deploys, reviews, evaluates, audits, and troubleshoots video streaming workflows across AWS media services (MediaConnect, MediaLive, MediaConvert, MediaPackage v2, MediaTailor, CloudFront). Includes per-service validation rules, cross-service workflow patterns for live streaming, linear channels, VOD pipelines, and live-to-VOD, service-specific troubleshooting, best practices assessment, cost optimization, encoder settings, DRM, SCTE-35 ad insertion, epoch locking, and CDN cache configuration.
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured framework for managing end-to-end video streaming pipelines using AWS Media Services. It acts as an orchestrator that enforces mandatory rule-loading sequences to ensure configurations adhere to service constraints, security best practices, and performance requirements. It covers the full lifecycle of live, linear, and VOD workflows, including ingest, encoding, packaging, ad insertion, and CDN delivery.

What it does

  • Provides a mandatory dependency-based workflow for building and modifying streaming pipelines.
  • Enforces the loading of specific service rules to prevent configuration errors.
  • Offers a comprehensive troubleshooting guide for cross-service signal chain issues.
  • Includes a discovery checklist to gather requirements before resource deployment.
  • Defines strict startup and shutdown sequences for live streaming events.
  • Provides best practices for cost optimization and resilience in media architectures.

When to use it

  • When building or modifying live, linear, or VOD video streaming workflows.
  • When troubleshooting errors, latency, or sync issues across AWS media services.
  • When auditing existing configurations for compliance or performance optimization.
  • When planning a new media project and needing to understand service dependencies.
  • When configuring complex features like SCTE-35 ad insertion, DRM, or epoch locking.

Advantages

  • Prevents common configuration errors by enforcing dependency-aware resource creation.
  • Ensures compliance with service-specific constraints and security policies.
  • Reduces troubleshooting time by providing structured, service-specific diagnostic paths.
  • Promotes architectural best practices for resilience and cost efficiency.
  • Standardizes the approach to complex media tasks like ad insertion and CDN integration.

Usage examples

“I need to set up a live event workflow using MediaConnect, MediaLive, and MediaPackage. What is the correct order?”
The agent will load the core rules, the live event workflow file, and the relevant service rules, then guide you through the dependency-ordered creation process starting with VPC/IAM, followed by MediaPackage, MediaConnect, and finally MediaLive.
“My MediaLive channel is failing to start and showing pipeline errors. How do I fix it?”
The agent will load the core rules and the MediaLive troubleshooting file, then prompt you to check specific pipeline failover settings and encoder configurations based on the loaded rules.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/aws/aws-media-services/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip aws-media-services.zip -d .agents/skills

Documentation by AWS

AWS Media Services

Use this skill when the user is doing ANY of the following with AWS media services:

  • Building or modifying a video workflow (ingest, encoding, packaging, ad insertion, CDN delivery)

  • Reviewing, evaluating, or auditing an existing or proposed configuration for best practices, compliance, or correctness

  • Troubleshooting errors, alerts, or unexpected behavior

  • Asking questions about service constraints, compatibility rules, encoder settings, IAM policies, security groups, DRM, SCTE-35, caching, scaling, or any other AWS media topic

  • Planning a new workflow and needs to understand requirements, dependencies, or the discovery checklist

  • Optimizing cost, resilience, or performance of an existing workflow

If the user mentions ANY AWS media service by name (MediaConnect, MediaLive, MediaConvert, MediaPackage, MediaTailor) or related concepts (HLS, DASH, CMAF, ABR ladder, SCTE-35, epoch locking, origin shield, CDI, SRT, RTMP, transcode, live streaming, VOD pipeline, ad insertion, SSAI), load this skill.

This file is the orchestrator. It tells you which reference files to load based on the user's task. Do not load all files at once. Load on demand per the routing table below.


MANDATORY FIRST STEP — Read Before Doing Anything Else

STOP. Before you make ANY API call, pull ANY resource configuration, write ANY code, or produce ANY recommendation, you MUST load the required rule files into context. No exceptions. This applies to every task type: building, modifying, evaluating, troubleshooting, or answering questions.

The rule content is split across:

  • references/service-rules-core.md — cross-service compatibility constraints, common agent mistakes, and security considerations. ALWAYS loaded.

  • references/service-rules-encoding.md — shared encoder settings (QVBR, GOP, profiles, quality tuning, deinterlacing). Loaded for any encoding task.

  • references/service-rules-mediaconnect.md

  • references/service-rules-medialive.md

  • references/service-rules-mediaconvert.md

  • references/service-rules-mediapackage.md

  • references/service-rules-mediatailor.md

  • references/service-rules-cloudfront.md

Per-service rule files are loaded conditionally based on which services the query involves. Without the relevant rules loaded, you will produce recommendations based on general knowledge that may contradict the documented rules, flag correct configurations as problems, or miss critical constraints entirely.

Sequence (every time):

  1. Read references/service-rules-core.md — confirm it is in context before proceeding. ALWAYS required.

  2. Determine the task type and consult the Task Routing tables below to identify both the workflow/troubleshooting file AND the per-service rules to co-load.

  3. For ad-hoc questions that don't match a workflow or troubleshooting category: if the user names specific service(s), load those service rule files. If the question is symptom-based or you cannot determine which services are involved, load ALL per-service rule files.

  4. Only then begin resource discovery, API calls, or implementation.

If you find yourself about to call aws medialive describe-channel or similar and you have NOT yet read the core rules file plus the relevant per-service rules, stop and go back to step 1.


Task Routing

Building or modifying a workflow

Determine the workflow type. Load the matching workflow file AND the per-service rules listed in the right column (the core rules file is already loaded from the mandatory first step above).

Workflow typeWorkflow fileService rules to co-load
Live event (ingest → encode → package → deliver)references/workflow-live-event.mdmediaconnect + medialive + encoding + mediapackage + cloudfront (+ mediatailor if ads)
Linear channel (24/7 with schedule, ad insertion)references/workflow-linear-channel.mdmedialive + encoding + mediapackage + mediatailor + cloudfront
VOD pipeline (file-based transcode → package → deliver)references/workflow-vod-pipeline.mdmediaconvert + encoding + mediapackage + cloudfront
Live-to-VOD (live + archive/harvest → VOD transcode)references/workflow-live-event.md + references/workflow-vod-pipeline.mdunion of live event + VOD pipeline
Ad insertion (SSAI/CSAI, MediaTailor scaling)references/workflow-ad-insertion.mdmedialive + encoding + mediapackage + mediatailor + cloudfront
Contribution transport (MediaConnect, SRT, DX, encoders)references/workflow-contribution-distribution.mdmediaconnect + medialive + encoding
Router-based switching (master control, dynamic routing, playout)references/workflow-contribution-distribution.mdmediaconnect + medialive + encoding
Resilience (dual-AZ, dual-region, epoch locking, multi-CDN, ops readiness)references/workflow-resilience-patterns.mdALL (cross-cutting)
Cost optimization (reserved vs on-demand, channel classes, right-sizing)references/workflow-cost-optimization.mdALL (cross-cutting)
Subtitles and accessibility (captions, multi-language, auto-captioning)references/workflow-subtitles-accessibility.mdmedialive + mediaconvert + encoding
Troubleshooting

Load the relevant troubleshooting file(s) for the problem area AND the per-service rules listed in the right column. The core rules file is already loaded from the mandatory first step above. Load only the files needed.

Problem areaTroubleshooting fileService rules to co-load
MediaConnect flow issues, source connectivity, VPC interfaces, MediaConnect Routerreferences/troubleshooting-mediaconnect.mdmediaconnect
MediaLive channel errors, alerts, encoding, pipeline failoverreferences/troubleshooting-medialive.mdmedialive + encoding
MediaPackage ingest failures, manifest issues, access denied, v1→v2 migrationreferences/troubleshooting-mediapackage.mdmediapackage
MediaConvert job failures, codec errors, output issues, automationreferences/troubleshooting-mediaconvert.mdmediaconvert + encoding
MediaTailor ad insertion, ADS issues, SSAI scaling, session managementreferences/troubleshooting-mediatailor.mdmediatailor + medialive + mediapackage + cloudfront
CloudFront origin errors, cache behavior, multi-CDN, Embedded POPs (ePOP)references/troubleshooting-cloudfront.mdcloudfront + mediapackage
Cross-service signal chain (no video, latency, sync, AZ alignment, IAM, failover)references/troubleshooting-pipeline.mdALL
Quick reference

For a quick answer about a specific service's constraints, valid parameter values, or compatibility rules:

  1. references/service-rules-core.md is already loaded (mandatory first step).

  2. If the user names specific service(s) in the query, load those per-service rule files (e.g. references/service-rules-medialive.md).

  3. If the question crosses service boundaries (e.g., MediaPackage→MediaTailor compatibility), the cross-service rules are already in service-rules-core.md.

  4. If you can't determine which services are involved, load ALL per-service rule files.

This includes the following topics:

  • MediaTailor scaling patterns (multi-region, CDN origin shield, prefetch)

  • MediaConnect Router (paired resilient zonal endpoints) and downstream NDI converter caveats

  • Epoch locking and cross-region failover

  • Contribution transport (SRT tuning, Direct Connect sizing, RTP+FEC)

  • Multi-CDN architecture patterns

  • CloudFront advanced patterns (Embedded POPs / ePOP, CF Functions, segment sharding)

  • Operational readiness for live events (capacity planning, KPI baselines)

  • DRM production patterns and MediaPackage v1→v2 migration

  • Audio, HDR, and codec configuration details


Workflow Discovery Checklist

Before creating ANY resources for a new workflow, gather requirements from the user in a fixed order (mode → cost/scale → approach → source → network → encoding → ad insertion → packaging → IAM → VOD-specific). Do not proceed until all required items are answered; later questions depend on earlier answers.

Load references/workflow-discovery-checklist.md for the full ordered question set whenever building or modifying a workflow.

Plan Validation (before presenting to user)

Before presenting a proposed configuration to the user, cross-check against the loaded service rules:

  • Codec/container compatibility (e.g., HEVC requires fMP4, not TS)

  • GOP/segment duration alignment across all ABR rungs

  • Dependency ordering (downstream before upstream)

  • IAM trust policy includes all required service principals + sts:TagSession

  • IAM permissions scoped to specific resource ARNs (no Resource: "*")

  • Security posture (CIDR scoped, OAC configured, no Principal: *)

  • All prerequisite resources included (IAM roles, VPC, MediaPackage channel MUST be in the plan before resources that depend on them)

Do NOT make API calls during this step. This is a rules-based review of the proposed plan against constraints already in context.

Agents MUST NOT skip dependency steps to save time. All prerequisites (IAM, VPC, MediaPackage channel, etc.) MUST be created before resources that reference them. Skipping steps and fixing errors reactively leads to circular troubleshooting loops. Execute the plan in dependency order.


Resource Creation Order

Respect dependency order — a resource must exist before anything that references it (live chain, VOD chain, live-to-VOD addition, and the common flow patterns table).

Load references/resource-creation-order.md for the full dependency chains and flow-pattern table when creating resources.

Startup and Shutdown (Live Only)

Start upstream first and poll each resource to its ready state before proceeding (STARTING ≠ running); shut down in reverse (STOPPING ≠ stopped). Poll on a tight ~5s cadence.

Load references/startup-shutdown.md for the ordered start/stop tables and the polling pattern (including MediaConnect Router lifecycle) when operating a live workflow.

Tooling

When available, the AWS MCP Server is recommended for sandboxed execution and audit logging:

  • AWS MCP Server (aws-mcp-server): AWS API access, Agent SOPs for guided multi-step workflows, and documentation search via search_documentation and read_documentation.

  • AWS IaC MCP Server (aws-iac-mcp-server): CloudFormation template validation, CDK documentation search, CDK code samples, and IaC best practices.

Large response warning: MediaLive describe-channel and MediaPackage list-* calls return very large JSON. Always use --query (JMESPath) to extract only the fields you need.

# Good — extract only what you need
aws medialive describe-channel --channel-id 12345 --query "{State:State,Name:Name,Id:Id}"
aws medialive list-channels --query "Channels[].{Name:Name,Id:Id,State:State}"
aws mediapackagev2 list-origin-endpoints --channel-group-name X --channel-name Y \
  --query "Items[].{Name:OriginEndpointName,Url:HlsManifests[0].Url}"

Files

references/troubleshooting-mediatailor.md

Troubleshooting: MediaTailor

Per-service troubleshooting for MediaTailor server-side ad insertion. Load service-rules-mediatailor.md alongside this file.

Table of Contents

  • The five stages

  • Symptom Router

  • No ads at all

  • Ads appear only from the second play

  • Some breaks fill, others do not

  • Skip reasons, and which ones are normal

  • Wrong ad, or the same ad everywhere

  • Beacons and impression counts

  • Latency and stale manifests

  • Targeting parameters not reaching the ad server

  • Log groups and how to join them

  • Before opening a support case


The five stages

Ad delivery is a pipeline, and every stage fails independently. Agents MUST work it top down and MUST stop at the first stage that fails, because the log proving one stage says nothing about the next.

#StageProof it passedWhere
1Break detectionAD_MARKER_FOUNDADS interaction log
2Ad decisionMAKING_ADS_REQUEST then VAST_RESPONSE then FILLED_AVAILADS interaction log
3Creative conditioningTRANSCODE_COMPLETED for the creativeUniqueIdtranscode log
4Manifest assemblyEXT-X-DISCONTINUITY plus ad segment URIs in the personalized media playlistfetch the manifest
5Delivery and reportingAvail.Impression, BEACON_FIREDmetrics, ADS log

The most common misdiagnosis in SSAI: FILLED_AVAIL records the ad decision, two stages before delivery. Agents MUST NOT conclude ads are playing from FILLED_AVAIL alone. If the creative was still conditioning, the avail renders empty and AdNotReady plus SkippedReason.NewCreative fire instead.

Symptom Router

IF no ads in any break, ever:
  → See "No ads at all"
IF ads absent on first play, present on replay:
  → See "Ads appear only from the second play" (this is usually correct behaviour)
IF some breaks fill and others do not:
  → See "Some breaks fill, others do not"
IF ads play but the wrong ad, or every viewer sees the same ad:
  → See "Wrong ad, or the same ad everywhere"
IF ads play but impressions are missing or doubled:
  → See "Beacons and impression counts"
IF playback starts slowly, or manifests go stale:
  → See "Latency and stale manifests"
IF ad targeting is wrong or the ad server sees no parameters:
  → See "Targeting parameters not reaching the ad server"
IF the break never closes (CUE-OUT with no CUE-IN):
  → LOAD references/troubleshooting-mediapackage.md — MediaPackage v2 tracks avails by
    segmentation_event_id and a mismatched CUE-IN leaves the avail open
IF SCTE-35 never reaches MediaTailor:
  → LOAD references/troubleshooting-medialive.md for the upstream chain

No ads at all

IF no ads in the personalized manifest:
  → Check: can you reproduce the session yourself?
  IF yes:
    → FIX: use per-session debug logging, NOT sampling. Append ?aws.logMode=DEBUG to the
      playback request for server-side reporting, or send "logMode": "DEBUG" in the session
      initialization body for client-side. That logs the one session you care about
    → Agents SHOULD prefer this over raising PercentEnabled: sampling picks sessions at
      random, so it may never capture the session under investigation, and it multiplies
      billed log volume across every session on the configuration
  IF no, and LogConfiguration.PercentEnabled is 0:
    → CAUSE: no per-session detail is being recorded, so nothing can be traced after the fact
    → FIX: raise it to a sampling percentage to catch an intermittent fault, then lower it
      again. CloudWatch metrics still publish by default, so fill rate, skip reasons and ADS
      errors remain visible in aggregate meanwhile
  → Check: does the ADS interaction log show AD_MARKER_FOUND for the session?
  IF no AD_MARKER_FOUND:
    → CAUSE: MediaTailor saw no break. The markers are missing or unparseable upstream
    → FIX: fetch the ORIGIN manifest directly and look for EXT-X-CUE-OUT / EXT-X-DATERANGE
      (HLS) or an EventStream (DASH). If absent, the fault is upstream: check MediaLive
      SCTE-35 passthrough and that MediaPackage exposes markers
    → NOTE: on VOD, #EXT-X-CUE-OUT:0 is the insertion marker and is a real break. Agents
      MUST NOT treat a zero duration as "no break declared"
  IF AD_MARKER_FOUND present:
    → Check: MAKING_ADS_REQUEST present?
    IF no MAKING_ADS_REQUEST:
      → CAUSE: the break was seen but no ad request was made
      → FIX: check AdDecisionServerUrl is set on the configuration FIRST. The API accepts a
        playback configuration with no ADS URL, so a partial PutPlaybackConfiguration can
        clear it and the stream keeps serving unpersonalized content with no error
      → Then check AvailSuppression mode and PersonalizationThresholdSeconds, which also
        suppress the request: avail suppression by position, the threshold by break duration
    IF MAKING_ADS_REQUEST present:
      → Check: what followed it?
      IF ERROR_ADS_TIMEOUT:
        → CAUSE: the ad server did not answer in time. Every timeout is an unfilled break
        → FIX: the timeout is configurable (AdsPersonalizationTimeouts, default 3000 ms,
          range 250 to 6000). Fix the ad server first; raising the timeout moves the latency
          into the manifest request path
      IF ERROR_ADS_INVALID_RESPONSE:
        → CAUSE: the ad server returned a non-200
        → FIX: ad server side. Note a 204 is an error here, not a no-fill signal: to signal
          no fill, return 200 with a VAST document containing zero <Ad> elements
      IF EMPTY_VAST_RESPONSE:
        → CAUSE: the ad server chose not to fill. This is an ad server decision, NOT a
          MediaTailor fault
        → FIX: escalate to ad ops with the adsRequestUrl from the log
      IF ERROR_ADS_RESPONSE_PARSE:
        → CAUSE: MediaTailor could not use the VAST. See "Some breaks fill, others do not"
      IF FILLED_AVAIL:
        → The decision succeeded. Go to stage 3 and check conditioning

Ads appear only from the second play

This is the designed cost of conditioning and is usually not a fault.

IF the first play shows no ad but a later play does:
  → Check: SkippedReason.NewCreative and AdNotReady in metrics
  IF both non-zero and falling:
    → CAUSE: first sighting. MediaTailor is conditioning the creative to the content ladder
    → FIX: none required. Confirm the same creativeUniqueId fills on a later request. To keep
      it off the viewer's path use prefetch, preconditioned ads, or a warm creative pool
  IF SkippedReason.NewCreative is high and NOT falling:
    → CAUSE: creatives are rotating faster than they can be conditioned, or the creative id
      changes every response
    → FIX: check that <Creative id> is stable. With no id, MediaTailor indexes by media file
      URL, so a cache-busting query string makes every request a brand-new creative and
      guarantees a permanent skip floor

A skip is per session, not per creative. Every session building a manifest for that break during the conditioning window skips independently, so at high concurrency a healthy service produces a large SkippedReason.NewCreative value. The count tracks concurrency, not health.

Some breaks fill, others do not

IF fill is partial:
  → Check: avail.skippedAds[].skippedReason inside FILLED_AVAIL records
  IF TRANSCODE_ERROR:
    → CAUSE: conditioning failed on the selected creative
    → FIX: MediaTailor conditions the HIGHEST-BITRATE MediaFile only, with no fallback.
      Confirm that file is a reachable, high-quality MP4. No ProRes, no odd resolutions
      such as 855x481
  IF NO_VARIANT_MATCH:
    → CAUSE: the creative could not be matched to a content rendition
    → FIX: align the creative ladder to the content ladder, or author a transcode profile
      covering every current variant. Creatives do NOT need to match content encoding;
      this is a matching failure, not a quality mismatch
  IF AVAIL_DURATION_EXCEEDED:
    → CAUSE: the ad server returned more ad time than the break holds. MediaTailor never
      clips an ad, so creatives that do not fit are dropped whole
    → FIX: size the pod with [session.avail_duration_secs] in the ADS URL
  IF LEFTOVER_AVAIL_EXCEEDED_THRESHOLD:
    → CAUSE: unfilled time exceeded PersonalizationThresholdSeconds, so the break was
      abandoned rather than partially filled
    → FIX: this is the setting doing its job. Raise the threshold or improve fill
  IF EARLY_CUE_IN:
    → CAUSE: the live signal closed the break early. Expected on live
  IF the response was rejected (ERROR_ADS_RESPONSE_PARSE):
    → CAUSE: the VAST breaks one of MediaTailor's structural rules
    → Check first for a granular event on the same session. The ADS interaction log defines
      ERROR_VAST_MISSING_CREATIVES, ERROR_VAST_MISSING_IMPRESSION, ERROR_VAST_MISSING_MEDIAFILES,
      ERROR_VAST_MISSING_OVERLAYS, ERROR_VAST_MULTIPLE_LINEAR, ERROR_VAST_MULTIPLE_TRACKING_EVENTS,
      ERROR_VAST_INVALID_MEDIA_FILE, ERROR_VAST_INVALID_VAST_AD_TAG_URI and three
      ERROR_VAST_REDIRECT_* events. One of those names the failing rule directly
    → NOTE: a crafted-fixture run did not surface any granular event, only
      ERROR_ADS_RESPONSE_PARSE. So agents MUST NOT conclude from its absence that the response
      is structurally fine, and SHOULD re-run with ?aws.logMode=DEBUG before deciding the log
      cannot say which rule failed
    → FIX: capture RAW_ADS_RESPONSE and inspect the document. Counting is per owning parent,
      not per <Ad>: at most one <Linear> per <Creative>, one <Duration> and one <MediaFiles>
      per <Linear> in use, at most one <TrackingEvents> per owner, at least one <Impression>
      per <InLine>

Skip reasons, and which ones are normal

The class column below is analytic, derived from each reason's mechanics. AWS classifies none of them, so agents MUST NOT attribute the classification to AWS.

ClassReasonsAction
Expected, self-resolvingNEW_CREATIVE, TRANSCODE_IN_PROGRESS, IMPORT_IN_PROGRESSnone, if the same creative fills later
Expected on liveEARLY_CUE_IN, AVAIL_DURATION_EXCEEDED, LEFTOVER_AVAIL_EXCEEDED_THRESHOLDtune pod sizing or thresholds, not a defect
Transient, fault when sustainedNO_VARIANT_MATCHalign ladders after an encoder or ladder change
FaultTRANSCODE_ERROR, IMPORT_ERROR, PROFILE_NOT_FOUND, INTERNAL_ERRORinvestigate

Agents SHOULD lead with what is normal before treating a skip as a defect, and SHOULD check whether the rate is steady rather than rising.

Corroborating a log count against a metric is sound, with one exception: SkippedReason.PersonalizationThresholdExceeded reports a duration, not a count, so it never matches a log count of skipped ads.

Wrong ad, or the same ad everywhere

IF every viewer sees the same ad:
  → CAUSE: a personalized manifest is being cached and shared
  → FIX: TTL=0 on every MediaTailor manifest and session behaviour. Ad segments are the
    opposite and SHOULD be cached hard
IF the wrong ad plays, with no error and no skip reason:
  → CAUSE: a reused <Creative id>. MediaTailor stores conditioned creatives by that id and
    serves the stored asset for a known id
  → FIX: a fresh unique id per creative. There is no documented way to purge a mis-indexed
    creative
IF ads play in the wrong order in a pod:
  → CAUSE: pod order comes from the ADS response, not from MediaTailor. The sequence
    attribute appears on both <Ad> and <Creative> in VAST
  → FIX: read the ordering out of RAW_ADS_RESPONSE first and confirm the ADS sent the
    order the customer expected. Agents MUST NOT attribute pod order to a MediaTailor
    setting: no documented playback configuration field controls it

Beacons and impression counts

IF ads deliver but Avail.Impression is zero:
  → Check: how does the session start?
  IF explicit POST /v1/session:
    → CAUSE: explicit init defaults to CLIENT-side reporting. MediaTailor fires nothing and
      CloudWatch sees no beacons. This is expected, not a fault
    → FIX: either the player fires beacons from the tracking endpoint, or move to implicit
      GET for server-side reporting
  IF implicit GET:
    → Check: did the player actually fetch the ad segments? Beacons fire only on real
      requests to the /segment/ URLs, never during manifest parsing
    IF the ad segments were never requested:
      → CAUSE: the ad played in no player. A manifest containing ads proves the decision,
        not the delivery
      → FIX: see the last Insights query below, which lists sessions that filled an avail
        and fired no beacon
    IF the segments were fetched and impressions are still zero:
      → CAUSE: the creatives carry no <Impression> URI. A VAST Ad with zero <Impression> is
        rejected outright, so check for ERROR_ADS_RESPONSE_PARSE and
        ERROR_VAST_MISSING_IMPRESSION too
IF impressions fire but no completes:
  → CAUSE: the creatives carry no complete tracking URI, or no ad played to the end
  → FIX: check the VAST for a complete event before assuming an audience problem.
    Completion rate is sum(Avail.Complete) / sum(Avail.Impression)
IF counts do not reconcile with the ad server:
  → Compare Avail.Impression against the ad server, NOT AdsBilled. AdsBilled counts
    insertions, so it answers a billing question rather than a measurement one

Agents MUST NOT fetch a tracking beacon URL while diagnosing. Reading the URL is safe; requesting it corrupts the customer's own impression counts.

Latency and stale manifests

IF start-up is slow:
  → Check: AdDecisionServer.Latency
  IF above ~1000 ms average:
    → CAUSE: the ad server sits inside the manifest request path, so its latency is viewer
      start-up delay on the first break. Wrapper chains are the usual cause (MediaTailor
      follows up to 7 VAST wrapper levels)
    → FIX: reduce wrapper depth, or use prefetch to take the ADS call off the manifest path.
      TPS-based traffic shaping is a PREFETCH schedule feature, not a general latency control
IF manifests are stale:
  → Split the age: Origin.Age (time the origin held it) against
    GetManifest.MediaTailorAge (time MediaTailor held it). They sum to GetManifest.Age
  → Neither is a latency. Personalization latency is GetManifest.Latency
  → NOTE: GetManifest.MediaTailorAge rises with manifest reuse, which is normal and not a
    performance problem
IF origin request volume looks too high:
  → Compare Origin.Age SampleCount against the content origin's own access logs. Do NOT use
    the Requests metric as the denominator: it is concurrent transactions per second across
    all request types, so the ratio is meaningless
  → NOTE: Origin.Age is not emitted at all when the response came from a CDN, so a CDN in
    front of the origin removes the only MediaTailor-side view of this
  IF every player request produces an origin fetch:
    → CAUSE: something makes the origin URL unique per request, so no fetch is ever reused
    → FIX: make the origin URL stable across requests. Agents MUST NOT advise removing origin
      authentication to win cache reuse. On a MediaPackage v2 origin, protect it with SigV4 and
      grant mediatailor.amazonaws.com principal access plus mediapackagev2:GetObject, which
      keeps the URL stable and the origin protected
  → Otherwise see "Scaling for large events" in service-rules-mediatailor.md
IF manifest fetches fail with 403 after removing a CDN from the origin leg:
  → CAUSE: the origin policy still allows only the CDN principal
  → FIX: grant mediatailor.amazonaws.com access to the endpoint before cutting the CDN over
    (scope the grant with aws:SourceAccount/aws:SourceArn per the confused-deputy rule in
    service-rules-cloudfront.md)

Targeting parameters not reaching the ad server

IF the ad server receives no parameters, or the wrong ones:
  → Check: adsRequestUrl on MAKING_ADS_REQUEST. Every [...] macro should be substituted
  IF a macro is still literal, or a parameter is empty:
    → CAUSE: unresolved macros become empty strings silently. No error, no skip reason, and
      the request is still sent
    → FIX: look for WARNING_URL_VARIABLE_SUBSTITUTION_FAILED, which carries adsRequestUrl.
      Confirm the syntax is square brackets: ${session.id} is NOT substituted
  IF the parameters are absent from the incoming request:
    → CAUSE: the CDN is not forwarding query strings, or the prefix is wrong for the entry
      point (manifest. on implicit init, manifestParams on explicit POST,
      manifestParams. on explicit GET)
    → FIX: forward all query strings on the manifest and session behaviours
  IF the ad server sees the CDN's user agent instead of the device:
    → FIX: forward User-Agent. MediaTailor proxies the player's user-agent and
      x-forwarded-for, but only if the CDN passes them through

Log groups and how to join them

Log groupCarries
MediaTailor/AdDecisionServerInteractionsbreak detection, ADS request and response, fill, skip reasons, beacons
MediaTailor/TranscodeServicecreative conditioning lifecycle
MediaTailor/ManifestServicemanifest generation and origin interaction
  • sessionId is the only precise join key across all three. originId is the playback configuration name and scopes a query to one configuration.

  • Agents MUST scope every Insights query with filter originId = '<config>'; an unscoped query returns other configurations' records because the legacy log groups are account-wide.

  • Vended logs SHOULD be preferred over legacy LEGACY_CLOUDWATCH delivery, which writes to those shared account-wide groups. configure-logs-for-playback-configuration --percent-enabled selects the legacy strategy.

  • 100% session logging is a diagnostic setting, not a steady state. Log delivery is billed per GB and RAW_ADS_RESPONSE multiplies volume, so agents SHOULD turn it up to investigate and back down afterwards. For a reproducible fault, ?aws.logMode=DEBUG on a single session is both cheaper and more certain than sampling.

  • Event types can be excluded per request with aws.adsInteractionLogExcludeEventTypes and aws.manifestServiceLogExcludeEventTypes, which agents SHOULD use to keep a high-percentage investigation affordable.

  • Agents MUST NOT reproduce the published Insights example queries. They filter on fields absent from the log schema (skipReason, creativeId, adBreakIndex do not exist; the field is avail.skippedAds[].skippedReason) and return zero rows.

Queries that do return rows

Run these against MediaTailor/AdDecisionServerInteractions. Replace <config> with the playback configuration name. Every one of them has been run against live records.

Where the funnel stops, for one configuration:

fields eventType
| filter originId = "<config>"
| filter eventType in ["AD_MARKER_FOUND","MAKING_ADS_REQUEST","VAST_RESPONSE",
    "EMPTY_VAST_RESPONSE","FILLED_AVAIL","BEACON_FIRED"]
| stats count() as events by eventType
| sort events desc

An empty ad response emits both EMPTY_VAST_RESPONSE and VAST_RESPONSE, so subtract the former from the latter before reading the fill step.

Which skip reasons dominate:

fields avail.skippedAds.0.skippedReason, avail.skippedAds.0.creativeUniqueId
| filter originId = "<config>" and eventType = "FILLED_AVAIL"
| filter ispresent(avail.skippedAds.0.skippedReason)
| stats count() as skips by avail.skippedAds.0.skippedReason
| sort skips desc

Logs Insights indexes array members positionally, so this reads only the first skipped ad per event. That is enough to rank causes, not to count them exactly.

One session end to end, in order, which is the query to run before escalating:

fields @timestamp, eventType, requestId, eventDescription
| filter sessionId = "<sessionId>"
| sort @timestamp asc
| limit 200

Sessions that planned an ad and fired no beacon:

fields sessionId
| filter originId = "<config>"
| filter eventType in ["FILLED_AVAIL","BEACON_FIRED"]
| fields (eventType = "FILLED_AVAIL") as isFill, (eventType = "BEACON_FIRED") as isBeacon
| stats sum(isFill) as fills, sum(isBeacon) as beacons by sessionId
| filter fills > 0 and beacons = 0
| sort fills desc
| limit 50

On server-side reporting that result is the population whose players never fetched the ad segments. A filter after stats can reference the aggregate aliases, which is what makes the last lines work. If sum() over a projected comparison returns empty, substitute strcontains(eventType, "FILLED_AVAIL"), which is documented to return 1 or 0.

Before opening a support case

Agents SHOULD gather all of the following, because a case without them will be sent back:

  • the playback configuration name and Region

  • the sessionId of a failing session, and the wall-clock time

  • the full GetPlaybackConfiguration output

  • the origin manifest fetched directly, and the personalized manifest for the same asset

  • the ADS interaction log records for that session, and the transcode log records for the creativeUniqueId

  • RAW_ADS_RESPONSE for the failing avail, if the fault is in the VAST

Before attaching any of the above to a support case or sharing it with ad ops, agents MUST redact credentials and tokens from AdDecisionServerUrl and adsRequestUrl (ADS API keys and auth tokens commonly ride in the query string), and MUST redact or truncate viewer identifiers — IP addresses (x-forwarded-for), device/advertising IDs, and session-level targeting values — from the ADS interaction log records and from RAW_ADS_RESPONSE (a third-party payload that can embed tracking URLs with viewer identifiers). Agents SHOULD share the sessionId and timestamp and let Support pull the raw records themselves rather than attaching them, where that is an option.

Escalate rather than guessing when the evidence points at INTERNAL_ERROR, NO_MODEL_CREATIVE_MATCH, or a manifest MediaTailor rejects with a 502 that a player can parse.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs a command-line tool

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · skills/specialized-skills/media-services-skills/aws-media-services · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-media-services.zip