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

  1. Retry the submit — 'transient-failure' is designed for retry; the underlying cause may resolve on its own
  2. Check the embedded error message for the HTTP status (e.g. 403 → auth/cookie expiry, 404 → stale URL)
  3. Verify network connectivity and that the manifestUrl is still reachable from a browser
  4. 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

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


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/46aea4bfbc271f02. Report an issue: GitHub.