AWS Media Services
AWSOfficialPublished by AWS
- Skill
- Tool integration
- Cloud and DevOps
- Apache-2.0
- No issues found
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
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/aws-media-services/downloadUnzip 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.mdreferences/service-rules-medialive.mdreferences/service-rules-mediaconvert.mdreferences/service-rules-mediapackage.mdreferences/service-rules-mediatailor.mdreferences/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):
Read
references/service-rules-core.md— confirm it is in context before proceeding. ALWAYS required.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.
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.
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 type | Workflow file | Service rules to co-load |
|---|---|---|
| Live event (ingest → encode → package → deliver) | references/workflow-live-event.md | mediaconnect + medialive + encoding + mediapackage + cloudfront (+ mediatailor if ads) |
| Linear channel (24/7 with schedule, ad insertion) | references/workflow-linear-channel.md | medialive + encoding + mediapackage + mediatailor + cloudfront |
| VOD pipeline (file-based transcode → package → deliver) | references/workflow-vod-pipeline.md | mediaconvert + encoding + mediapackage + cloudfront |
| Live-to-VOD (live + archive/harvest → VOD transcode) | references/workflow-live-event.md + references/workflow-vod-pipeline.md | union of live event + VOD pipeline |
| Ad insertion (SSAI/CSAI, MediaTailor scaling) | references/workflow-ad-insertion.md | medialive + encoding + mediapackage + mediatailor + cloudfront |
| Contribution transport (MediaConnect, SRT, DX, encoders) | references/workflow-contribution-distribution.md | mediaconnect + medialive + encoding |
| Router-based switching (master control, dynamic routing, playout) | references/workflow-contribution-distribution.md | mediaconnect + medialive + encoding |
| Resilience (dual-AZ, dual-region, epoch locking, multi-CDN, ops readiness) | references/workflow-resilience-patterns.md | ALL (cross-cutting) |
| Cost optimization (reserved vs on-demand, channel classes, right-sizing) | references/workflow-cost-optimization.md | ALL (cross-cutting) |
| Subtitles and accessibility (captions, multi-language, auto-captioning) | references/workflow-subtitles-accessibility.md | medialive + 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 area | Troubleshooting file | Service rules to co-load |
|---|---|---|
| MediaConnect flow issues, source connectivity, VPC interfaces, MediaConnect Router | references/troubleshooting-mediaconnect.md | mediaconnect |
| MediaLive channel errors, alerts, encoding, pipeline failover | references/troubleshooting-medialive.md | medialive + encoding |
| MediaPackage ingest failures, manifest issues, access denied, v1→v2 migration | references/troubleshooting-mediapackage.md | mediapackage |
| MediaConvert job failures, codec errors, output issues, automation | references/troubleshooting-mediaconvert.md | mediaconvert + encoding |
| MediaTailor ad insertion, ADS issues, SSAI scaling, session management | references/troubleshooting-mediatailor.md | mediatailor + medialive + mediapackage + cloudfront |
| CloudFront origin errors, cache behavior, multi-CDN, Embedded POPs (ePOP) | references/troubleshooting-cloudfront.md | cloudfront + mediapackage |
| Cross-service signal chain (no video, latency, sync, AZ alignment, IAM, failover) | references/troubleshooting-pipeline.md | ALL |
Quick reference
For a quick answer about a specific service's constraints, valid parameter values, or compatibility rules:
references/service-rules-core.mdis already loaded (mandatory first step).If the user names specific service(s) in the query, load those per-service rule files (e.g.
references/service-rules-medialive.md).If the question crosses service boundaries (e.g., MediaPackage→MediaTailor compatibility), the cross-service rules are already in
service-rules-core.md.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 viasearch_documentationandread_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
- ATTRIBUTION.mdAdded by AutoGineer930 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md11.6 KiB
- references/resource-creation-order.md2.3 KiB
- references/service-rules-cloudfront.md9.6 KiB
- references/service-rules-core.md16.6 KiB
- references/service-rules-encoding.md6.3 KiB
- references/service-rules-mediaconnect.md11.3 KiB
- references/service-rules-mediaconvert.md1.3 KiB
- references/service-rules-medialive.md9.4 KiB
- references/service-rules-mediapackage.md6.6 KiB
- references/service-rules-mediatailor.md20.6 KiB
- references/startup-shutdown.md2.2 KiB
- references/troubleshooting-cloudfront.md4.9 KiB
- references/troubleshooting-mediaconnect.md4.7 KiB
- references/troubleshooting-mediaconvert.md4.3 KiB
- references/troubleshooting-medialive.md5.7 KiB
- references/troubleshooting-mediapackage.md5.7 KiB
- references/troubleshooting-mediatailor.md22.2 KiB
- references/troubleshooting-pipeline.md6.2 KiB
- references/workflow-ad-insertion.md7.9 KiB
- references/workflow-contribution-distribution.md12.7 KiB
- references/workflow-cost-optimization.md13.8 KiB
- references/workflow-discovery-checklist.md4.4 KiB
- references/workflow-linear-channel.md4.7 KiB
- references/workflow-live-event.md20.1 KiB
- references/workflow-resilience-patterns.md5.6 KiB
- references/workflow-subtitles-accessibility.md3.4 KiB
- references/workflow-vod-pipeline.md5.4 KiB
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.
| # | Stage | Proof it passed | Where |
|---|---|---|---|
| 1 | Break detection | AD_MARKER_FOUND | ADS interaction log |
| 2 | Ad decision | MAKING_ADS_REQUEST then VAST_RESPONSE then FILLED_AVAIL | ADS interaction log |
| 3 | Creative conditioning | TRANSCODE_COMPLETED for the creativeUniqueId | transcode log |
| 4 | Manifest assembly | EXT-X-DISCONTINUITY plus ad segment URIs in the personalized media playlist | fetch the manifest |
| 5 | Delivery and reporting | Avail.Impression, BEACON_FIRED | metrics, 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 chainNo 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 conditioningAds 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 floorA 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.
| Class | Reasons | Action |
|---|---|---|
| Expected, self-resolving | NEW_CREATIVE, TRANSCODE_IN_PROGRESS, IMPORT_IN_PROGRESS | none, if the same creative fills later |
| Expected on live | EARLY_CUE_IN, AVAIL_DURATION_EXCEEDED, LEFTOVER_AVAIL_EXCEEDED_THRESHOLD | tune pod sizing or thresholds, not a defect |
| Transient, fault when sustained | NO_VARIANT_MATCH | align ladders after an encoder or ladder change |
| Fault | TRANSCODE_ERROR, IMPORT_ERROR, PROFILE_NOT_FOUND, INTERNAL_ERROR | investigate |
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 itBeacons 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 oneAgents 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 throughLog groups and how to join them
| Log group | Carries |
|---|---|
MediaTailor/AdDecisionServerInteractions | break detection, ADS request and response, fill, skip reasons, beacons |
MediaTailor/TranscodeService | creative conditioning lifecycle |
MediaTailor/ManifestService | manifest generation and origin interaction |
sessionIdis the only precise join key across all three.originIdis 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_CLOUDWATCHdelivery, which writes to those shared account-wide groups.configure-logs-for-playback-configuration --percent-enabledselects the legacy strategy.100% session logging is a diagnostic setting, not a steady state. Log delivery is billed per GB and
RAW_ADS_RESPONSEmultiplies volume, so agents SHOULD turn it up to investigate and back down afterwards. For a reproducible fault,?aws.logMode=DEBUGon a single session is both cheaper and more certain than sampling.Event types can be excluded per request with
aws.adsInteractionLogExcludeEventTypesandaws.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,adBreakIndexdo not exist; the field isavail.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 descAn 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 descLogs 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 200Sessions 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 50On 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
sessionIdof a failing session, and the wall-clock timethe full
GetPlaybackConfigurationoutputthe 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
creativeUniqueIdRAW_ADS_RESPONSEfor 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