{"record":{"id":"c3d5cf9d1a03c0cb","repo":"subhra74/xdm","slug":"unable-to-download-hls-manifest","errorCode":null,"errorMessage":"Unable to download HLS manifest","messagePattern":"Unable to download HLS manifest","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/XDM/XDM.Core/Downloader/Adaptive/Hls/MultiSourceHLSDownloader.cs","lineNumber":191,"sourceCode":"                        if (status[1] != HttpStatusCode.OK) return status[1];\r\n                        return null;\r\n                    }\r\n                    else\r\n                    {\r\n                        if (status[0] != HttpStatusCode.OK) return status[0];\r\n                        return null;\r\n                    }\r\n                }\r\n\r\n                if (!success)\r\n                {\r\n                    var statusCode = FindErrorStatus();\r\n                    if (statusCode.HasValue)\r\n                    {\r\n                        throw new Exception($\"Invalid response code: {statusCode.Value}\",\r\n                            new HttpException(statusCode.Value.ToString(), null, statusCode.Value));\r\n                    }\r\n                    throw new Exception(\"Unable to download HLS manifest\");\r\n                }\r\n\r\n                var playlists = new Dictionary<string, HlsPlaylist>();\r\n                if (state.Demuxed)\r\n                {\r\n                    playlists[\"video\"] = HlsParser.ParseMediaSegments(results[0]!.Split('\\n'), state.NonMuxedVideoPlaylistUrl.ToString());\r\n                    playlists[\"audio\"] = HlsParser.ParseMediaSegments(results[1]!.Split('\\n'), state.NonMuxedAudioPlaylistUrl.ToString());\r\n\r\n                    this._state.VideoContainerFormat = GuessContainerFormatFromPlaylist(playlists[\"video\"]);\r\n                    this._state.AudioContainerFormat = GuessContainerFormatFromPlaylist(playlists[\"audio\"]);\r\n                    \r\n                    var ext = FileExtensionHelper.GuessContainerFormatFromSegmentExtension(\r\n                            this._state.VideoContainerFormat, this._state.AudioContainerFormat);\r\n                    TargetFileName = Path.GetFileNameWithoutExtension(TargetFileName ?? \"video\")\r\n                            + ext;\r\n\r\n                    Log.Debug($\"Guessed Demuxed formats - VideoContainerFormat: {this._state.VideoContainerFormat} AudioContainerFormat: {this._state.AudioContainerFormat}\");\r\n                    Log.Debug($\"Guessed - ext: {ext} TargetFileName: {TargetFileName}\");\r","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/subhra74/xdm/blob/1ca5a25aae007826c859c81bea494e7c102e1242/app/XDM/XDM.Core/Downloader/Adaptive/Hls/MultiSourceHLSDownloader.cs#L173-L209","documentation":"The fallback branch of MultiSourceHLSDownloader.ProbeTarget: when the HLS manifest download failed but FindErrorStatus() found no specific HTTP status code, XDM throws 'Unable to download HLS manifest'. This indicates a failure to fetch the manifest without an identifiable HTTP error response (e.g. connectivity loss or an exception without a captured status).","triggerScenarios":"ProbeTarget's manifest download task completes with success=false and FindErrorStatus() returns null/HasValue==false, so no HTTP status is attributed to the failure.","commonSituations":"Network drop or DNS failure while fetching the m3u8; TLS errors; server closing the connection mid-response; proxy failures; manifest host unreachable.","solutions":["Check basic network connectivity to the manifest host (curl the m3u8 URL to reproduce)","Verify the m3u8 URL is current; re-capture it from the page if the download is old","Check proxy/firewall/TLS interception that can break the request without a clean HTTP status","Retry the download; transient network failures surface as this unspecific error"],"exampleFix":"// before\nthrow new Exception(\"Unable to download HLS manifest\");\n// after\nLog.Warn(\"HLS manifest fetch failed without an HTTP status; likely network error\");\nthrow new DownloadException(ErrorCode.NetworkFailure,\n    \"Unable to download HLS manifest (no HTTP status captured; check connectivity)\");","handlingStrategy":"retry","validationCode":"// Confirm the manifest is reachable before calling ProbeTarget\nvar probe = await http.SendAsync(new HttpRequestMessage(HttpMethod.Head, manifestUrl));\nif (!probe.IsSuccessStatusCode)\n    throw new InvalidOperationException($\"Manifest unreachable: {(int)probe.StatusCode}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    downloader.ProbeTarget();\n}\ncatch (Exception ex) when (ex.Message == \"Unable to download HLS manifest\")\n{\n    Log.Warn(\"HLS manifest fetch failed without HTTP status; retrying after network check\");\n    await WaitForNetworkAsync();\n    downloader.ProbeTarget();\n}","preventionTips":["Verify network connectivity/DNS before starting HLS downloads","Check proxy, VPN, and TLS interception which cause failures with no HTTP status","Validate the m3u8 URL is current before probing","Retry with backoff; this unspecific failure is often transient"],"tags":["hls","streaming","network","manifest"],"backgroundTag":"http-request-failed","analyzedSha":"1ca5a25aae007826c859c81bea494e7c102e1242","analyzedAt":"2026-09-13T20:37:40.968Z","contentChangedAt":"2026-09-13T20:37:40.968Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}