AlistGo/alist · error

open download file failed: %w

Error message

open download file failed: %w

What it means

Returned inside the range-reader closure of HalalCloud's file-open path. Inspection of the region shows a defect: `err` at this point is a leftover variable from an earlier scope (the code just computed `length` from httpRange/size), so the check `if err != nil` can only fire if a stale outer err is non-nil, wrapping it with %w. In a correctly scoped version this guard is meant to surface a range/parameter error before constructing openObject.

Source

Thrown at drivers/halalcloud/driver.go:260

				return nil, err
			}
			addressDuration = sliceAddress.ExpireAt
			fileAddrs = append(fileAddrs, sliceAddress.Addresses...)
			startIndex = endIndex
			nodesIndex -= 200
		}

	}

	size := result.FileSize
	chunks := getChunkSizes(result.Sizes)
	resultRangeReader := func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) {
		length := httpRange.Length
		if httpRange.Length >= 0 && httpRange.Start+httpRange.Length >= size {
			length = -1
		}
		if err != nil {
			return nil, fmt.Errorf("open download file failed: %w", err)
		}
		oo := &openObject{
			ctx:     ctx,
			d:       fileAddrs,
			chunk:   &[]byte{},
			chunks:  &chunks,
			skip:    httpRange.Start,
			sha:     result.Sha1,
			shaTemp: sha1.New(),
		}

		return readers.NewLimitedReadCloser(oo, length), nil
	}

	var duration time.Duration
	if addressDuration != 0 {
		duration = time.Until(time.UnixMilli(addressDuration))
	} else {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Upgrade the driver if the stale-err bug is fixed upstream — the guard should test the range parameters, not a leftover err.
  2. Retry the open: re-fetch the file metadata (result) so err starts nil, then issue the range read.
  3. If reproducing consistently for one file, re-upload / re-hash the file — a corrupt chunk map makes size/range math invalid.
  4. As a local patch, restructure so length computation errors are captured into a fresh error variable inside the closure.

Example fix

// before (bug: wraps stale outer err)
if err != nil {
    return nil, fmt.Errorf("open download file failed: %w", err)
}

// after: validate the range inputs themselves
if httpRange.Start < 0 || (size > 0 && httpRange.Start >= size) {
    return nil, fmt.Errorf("open download file failed: invalid range start %d for size %d", httpRange.Start, size)
}
Defensive patterns

Strategy: retry

Try / catch

r, err := link.Get(ctx, rangeHdr)
if err != nil {
    if strings.Contains(err.Error(), "open download file failed") {
        // stale metadata is the usual cause: re-open once with fresh result
        r, err = link.Get(ctx, rangeHdr)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Opening a HalalCloud download with a byte range when an earlier operation in the same function (e.g. metadata/result fetch) left err non-nil; reading files whose reported FileSize disagrees with the chunk map in result.Sizes.

Common situations: Range requests (video seeking, resumable downloads) against files whose chunk layout changed server-side after the file handle was opened; driver version where the stale-err scoping bug is present, making previously-cleared errors resurface at open time.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/b89bc3154130f592. Report an issue: GitHub.