agalwood/Motrix · error · BridgeReceiverError
transient-failure
transient-failure
Error message
manifest fetch failed: ${msg} What it means
Thrown by HlsDashPipeline.dispatch when the primary manifest fetch (fetchManifest) rejects. The underlying fetch error message is wrapped into a BridgeReceiverError with code 'transient-failure', signaling to the extension that this is a retryable network-level failure, not a permanent rejection. This covers the initial GET of the HLS master/media playlist or DASH MPD.
Source
Thrown at src/core/bridge-receiver/pipelines/hls-dash-pipeline.ts:54
export class HlsDashPipeline {
constructor(private readonly deps: HlsDashPipelineDeps) {}
async dispatch(
adapted: AdaptedHls | AdaptedDash
): Promise<{ taskId: string }> {
const { fetchManifest, coordinator } = this.deps
const headers = adapted.sanitizedHeaders
// ffmpeg needs an output extension or it can't pick a muxer (exit 234) —
// a manifest-derived finalName may lack one. Compute once for all branches.
const finalName = ensureMediaExtension(adapted.finalName, adapted.container)
// --- fetch primary manifest ---
let manifestText: string
try {
manifestText = await fetchManifest(adapted.manifestUrl, { headers })
} catch (e) {
const msg = e instanceof Error ? e.message : String(e)
throw new BridgeReceiverError(
'transient-failure',
`manifest fetch failed: ${msg}`
)
}
try {
if (adapted.kind === 'dash') {
// DASH
const { video, audio } = parseDash(manifestText, adapted.manifestUrl)
const job: MediaJob = {
taskId: adapted.taskId,
kind: 'dash',
video,
...(audio !== undefined ? { audio } : {}),
headers,
saveDir: adapted.saveDir,
finalName,
sourceMeta: adapted.sourceMeta,View on GitHub (pinned to 1a708ee577)
Solutions
- Retry the submit — 'transient-failure' is designed for retry; the underlying cause may resolve on its own
- Check the embedded error message for the HTTP status (e.g. 403 → auth/cookie expiry, 404 → stale URL)
- Verify network connectivity and that the manifestUrl is still reachable from a browser
- For 403s, ensure cookies/headers are correctly forwarded — check that serialized headers include auth tokens like SESSDATA
Defensive patterns
Strategy: retry
Validate before calling
async function isManifestReachable(url: string, headers?: Record<string, string>): Promise<boolean> {
try {
const res = await fetch(url, { headers, method: 'HEAD' })
return res.ok
} catch { return false }
} Try / catch
try {
await receiver.handleSubmit(params)
} catch (e) {
if (e instanceof BridgeReceiverError && e.code === 'transient-failure' && e.message.startsWith('manifest fetch failed')) {
// Retry with backoff — transient by design
await sleep(2000)
await receiver.handleSubmit(params)
} else throw e
} Prevention
- Treat 'transient-failure' as retryable in your error handler with exponential backoff
- Check the embedded HTTP status in the message to distinguish auth expiry (403) from outages (503)
When it happens
Trigger: fetchManifest(adapted.manifestUrl, { headers }) rejects due to a network error, DNS failure, connection reset, HTTP 4xx/5xx, TLS error, or timeout. The manifestUrl is the primary playlist/MPD URL from the adapted selection.
Common situations: CDN outage or transient 503; expired signed URL (403); geo-blocked manifest; DNS resolution failure in a restrictive network; manifest URL became stale between extension detection and submit; proxy/firewall blocking the request.
Related errors
- Key must be 16 bytes, got ${key.length} from ${uri}
- GeoIPDownloadFailed
- unsupported-live
- unsupported-encryption
- unsupported-master
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/46aea4bfbc271f02.
Report an issue: GitHub.