subhra74/xdm · critical · NonRetriableException

DiskError

DiskError

Error message

Disk error :: {piece.Id}

What it means

In PieceGrabber.CopyWithFixedLength, writing downloaded bytes to the target stream raises an IOException (disk full, permission, hardware fault). The grabber logs it and wraps it as NonRetriableException with ErrorCode.DiskError since retrying a disk problem will not help.

Solutions

  1. Free disk space on the destination drive and restart the download.
  2. Choose a different download destination on a healthy local volume.
  3. Close programs locking the target file (antivirus, sync clients) or add an exclusion.
  4. Run chkdsk/fsck to check the disk for errors.

Example fix

// before
Download(url, destDisk); // destDisk has 100MB free, file is 2GB
// after
if (GetFreeSpace(destDisk) < expectedSize) {
    destDisk = PickDriveWithSpace(expectedSize); // avoid DiskError mid-download
}
Defensive patterns

Strategy: validation

Validate before calling

var drive = new DriveInfo(Path.GetPathRoot(destPath));
if (drive.AvailableFreeSpace < expectedSizeBytes)
    throw new IOException($"Insufficient space on {drive.Name}");

Try / catch

try { Download(url, dest); }
catch (DownloadException e) when (e.ErrorCode == ErrorCode.DiskError) {
    Log.Error(e.InnerException, "Disk problem - not retrying");
    FreeSpaceOrChangeDestination();
}

Prevention

When it happens

Trigger: targetStream.Write throws IOException while copying a fixed-length piece - typically disk full, file locked by another process, or an I/O device error on the destination volume.

Common situations: Destination drive out of space during a large download, antivirus/backup tools locking the file, removable drive disconnecting, quota limits exceeded, bad sectors.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of subhra74/xdm@1ca5a25aae (2026-09-13). Data as JSON: /api/errors/800916b8e2a9eb62. Report an issue: GitHub.

Appendix: source

Thrown at app/XDM/XDM.Core/Downloader/Progressive/PieceGrabber.cs:299

                            break;
                        }
                    }
                    var x = sourceStream.Read(BUF, 0,
                        (int)Math.Min(BUF.Length, remaining));
                    this.CancellationToken.ThrowIfCancellationRequested();
                    if (x == 0)
                    {
                        throw new DownloadException(ErrorCode.Generic, "Unexpected EOF :: " + piece.Id);
                    }
                    try
                    {
                        targetStream.Write(BUF, 0, x);
                        count += x;
                    }
                    catch (IOException ioe)
                    {
                        Log.Debug(ioe, "Disk error");
                        throw new NonRetriableException(ErrorCode.DiskError, "Disk error :: " + piece.Id, ioe);
                    }
                    if (this.CancellationToken.IsCancellationRequested) return;
                    this.callback?.UpdateDownloadedBytesCount(this.pieceId, x);
                    this.callback?.ThrottleIfNeeded();
                }
            }
            finally
            {
#if !NET35
                System.Buffers.ArrayPool<byte>.Shared.Return(BUF, false);
#endif
            }
        }

        private void CloseUnfinishedRequest(long count)
        {
            if (actualHttpResponseSize - count != 0)
            {

View on GitHub (pinned to 1ca5a25aae)