{"record":{"id":"b63cc0172525c6f9","repo":"subhra74/xdm","slug":"nonresumable","errorCode":"NonResumable","errorMessage":"Resume not supported","messagePattern":"Resume not supported","errorType":"error_code","errorClass":"NonRetriableException","httpStatus":null,"severity":"error","filePath":"app/XDM/XDM.Core/Downloader/Progressive/PieceGrabber.cs","lineNumber":170,"sourceCode":"            this.sleepHandle.Set();\r\n            this.sleepHandle.Close();\r\n            this.pieceId = null;\r\n            this.callback = null;\r\n            try { this.fileWriterStream?.Dispose(); } catch { }\r\n        }\r\n\r\n        private HttpResponse Connect()\r\n        {\r\n            HttpResponse? response = null;\r\n            var error = true;\r\n            try\r\n            {\r\n                if (this.callback == null || this.pieceId == null) throw new OperationCanceledException();\r\n                var piece = this.callback.GetPiece(this.pieceId);\r\n                var firstRequest = this.callback.IsFirstRequest(piece.StreamType);\r\n\r\n                if (piece.Length == -1 && !this.callback.IsFirstRequest(piece.StreamType))\r\n                    throw new NonRetriableException(ErrorCode.NonResumable, \"Resume not supported\");\r\n\r\n                var hc = this.callback.GetSharedHttpClient(this.pieceId);\r\n                if (hc == null) throw new OperationCanceledException();\r\n                request = CreateRequest(hc, piece);\r\n                response = hc.Send(request);\r\n                CancellationToken.ThrowIfCancellationRequested();\r\n                response.EnsureSuccessStatusCode();\r\n\r\n                var status = response.StatusCode;\r\n                var contentLength = response.ContentLength;\r\n                if (response.Compressed)\r\n                {\r\n                    contentLength = -1;\r\n                    if (response.StatusCode == HttpStatusCode.PartialContent)\r\n                    {\r\n                        status = HttpStatusCode.OK;\r\n                    }\r\n                }\r","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/subhra74/xdm/blob/1ca5a25aae007826c859c81bea494e7c102e1242/app/XDM/XDM.Core/Downloader/Progressive/PieceGrabber.cs#L152-L188","documentation":"Thrown in PieceGrabber.Connect when a piece's total length is unknown (-1) and the request is not the first request for that stream type. The server did not provide a content length, so the downloader cannot resume into a partial stream and throws NonRetriableException with ErrorCode.NonResumable. This failure is deliberately not retried.","triggerScenarios":"Calling Connect on a non-first request where callback.GetPiece(...).Length == -1, i.e. a resume attempt against a response with no usable length (chunked transfer or missing Content-Length) for that stream type.","commonSituations":"Servers that stream with Transfer-Encoding: chunked, dynamic responses (no Content-Length), resuming a download whose original headers no longer advertise a length, misconfigured proxy stripping Content-Length.","solutions":["Restart the download from scratch (single connection, no resume) instead of resuming the piece.","Verify the server supports Content-Length and Range requests; fall back to single-source download if not.","Ensure IsFirstRequest/stream bookkeeping is correct so length-known first requests are not mistaken for resumes."],"exampleFix":"// before\nvar piece = callback.GetPiece(pieceId); // Length == -1 on resume -> NonResumable\n// after\nif (piece.Length == -1) {\n    // restart download without resume\n    RestartDownload(disableResume: true);\n}","handlingStrategy":"fallback","validationCode":"var req = new HttpRequestMessage(HttpMethod.Head, url);\nvar resp = await client.SendAsync(req);\nbool canResume = resp.Headers.AcceptRanges.Contains(\"bytes\") && resp.Content.Headers.ContentLength.HasValue;\nif (!canResume) disableResume = true;","typeGuard":"bool IsResumable(long pieceLength) => pieceLength != -1;","tryCatchPattern":"try { grabber.Connect(); }\ncatch (DownloadException e) when (e.ErrorCode == ErrorCode.NonResumable) {\n    RestartDownloadWithoutResume();\n}","preventionTips":["Probe Accept-Ranges/Content-Length before resuming","Fall back to single-connection download for chunked sources","Keep stream/first-request bookkeeping accurate"],"tags":["http","resume","download"],"backgroundTag":"operation-not-supported","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"}