agalwood/Motrix · warning · Error
manifest too large: ${text.length} > ${max}
Error message
manifest too large: ${text.length} > ${max} What it means
Plain Error thrown by fetchManifest when the response body length exceeds opts.maxBytes (default 5 MiB). The guard prevents a malicious or misconfigured origin from exhausting memory by serving an arbitrarily large 'manifest' — a denial-of-service protection at the trust boundary.
Source
Thrown at src/core/media/manifest-fetcher.ts:23
opts: {
headers?: Record<string, string>
fetchImpl?: typeof fetch
maxBytes?: number
} = {}
): Promise<string> {
const doFetch = opts.fetchImpl ?? fetch
const res = await doFetch(url, {
method: 'GET',
headers: opts.headers ?? {},
redirect: 'follow',
})
if (!res.ok) {
throw new Error(`manifest fetch failed: HTTP ${res.status}`)
}
const text = await res.text()
const max = opts.maxBytes ?? DEFAULT_MAX
if (text.length > max) {
throw new Error(`manifest too large: ${text.length} > ${max}`)
}
return text
}
View on GitHub (pinned to 1a708ee577)
Solutions
- Verify the URL points at a manifest (HLS .m3u8 / DASH .mpd) and not at a media file.
- If the manifest is legitimately large, raise opts.maxBytes to an explicit value you have reasoned about.
- Inspect Content-Type and Content-Length of the response before/after to confirm it is actually a manifest.
- If a CDN is returning a 200 HTML error page, fix the upstream routing.
Example fix
// before
const text = await fetchManifest(url, {})
// after — confirm it's a manifest and raise cap if legitimate
const text = await fetchManifest(url, {
maxBytes: 10 * 1024 * 1024,
headers: { Accept: 'application/vnd.apple.mpegurl, application/dash+xml' },
})
if (!/^#|<\?xml|<MPD/.test(text.trimStart())) {
throw new Error('Response does not look like a manifest')
} Defensive patterns
Strategy: validation
Validate before calling
function looksLikeManifest(text: string): boolean {
return /^\s*(#|<\?xml|<MPD)/.test(text)
}
const text = await fetchManifest(url, { maxBytes: 10 * 1024 * 1024 })
if (!looksLikeManifest(text)) {
throw new Error('Response is not a manifest (HLS/DASH). Check the URL.')
} Type guard
function looksLikeManifest(text: string): boolean {
return /^\s*(#EXTM3U|<\?xml|<MPD\b)/.test(text)
} Try / catch
try {
const text = await fetchManifest(url, { maxBytes })
} catch (e) {
if (/manifest too large/.test(String(e))) {
// either raise maxBytes after reasoning, or reject the URL as not-a-manifest
} else throw e
} Prevention
- Confirm URL points at a manifest and not a media segment before fetching.
- Set opts.maxBytes to a value you have reasoned about for your asset catalogue.
- Inspect Content-Type/Content-Length of suspicious responses to detect CDN error pages.
When it happens
Trigger: Calling fetchManifest against a URL whose response body is larger than the cap — e.g. an HLS master with thousands of variants, a DASH MPD that inlines SegmentTimeline with millions of <S> entries, or accidentally pointing the manifest fetcher at a media segment / large JSON endpoint.
Common situations: URL dispatch bug sending the fetcher at a media segment or full MP4 instead of the manifest; oversized live-window manifests; CDN returning an error page (large HTML) with a 200 status; legitimate large manifests that exceed the 5 MiB default.
Related errors
- manifest fetch failed: HTTP ${res.status}
- Key must be 16 bytes, got ${key.length} from ${uri}
- plugin.http.scheme_not_allowed
- plugin.http.timeout
- plugin.http.network
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/a52405494f0ffc20.
Report an issue: GitHub.