AlistGo/alist · error

failed extracting file size

Error message

failed extracting file size

What it means

In checkTotalBytes, when the Content-Range header's total part exists (not '*') but strconv.ParseInt fails, the original parse error is replaced with this opaque message. The total file size is needed to plan chunk ranges, so an unparseable total aborts the download (setErr + cancel).

Source

Thrown at internal/net/request.go:499

	if len(contentRange) == 0 {
		// ContentRange is nil when the full file contents is provided, and
		// is not chunked. Use ContentLength instead.
		if resp.ContentLength > 0 {
			totalBytes = resp.ContentLength
		}
	} else {
		parts := strings.Split(contentRange, "/")

		total := int64(-1)

		// Checking for whether a numbered total exists
		// If one does not exist, we will assume the total to be -1, undefined,
		// and sequentially download each chunk until hitting a 416 error
		totalStr := parts[len(parts)-1]
		if totalStr != "*" {
			total, err = strconv.ParseInt(totalStr, 10, 64)
			if err != nil {
				err = fmt.Errorf("failed extracting file size")
			}
		} else {
			err = fmt.Errorf("file size unknown")
		}

		totalBytes = total
	}
	if totalBytes != d.params.Size && err == nil {
		err = fmt.Errorf("expect file size=%d unmatch remote report size=%d, need refresh cache", d.params.Size, totalBytes)
	}
	if err != nil {
		// _ = d.interrupt()
		d.setErr(err)
		d.cancel(err)
	}
	return err

}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Capture the raw Content-Range header to see what the server actually sent.
  2. Fix/replace the backend or proxy that emits a malformed Content-Range total.
  3. If you control the server, emit 'bytes start-end/total' with a numeric total.
  4. If the size is genuinely unknown, have the server send '*' so the downloader uses its sequential 416-based path instead.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate a Content-Range total before relying on it
parts := strings.Split(contentRange, "/")
if total := parts[len(parts)-1]; total != "*" {
    if _, err := strconv.ParseInt(total, 10, 64); err != nil {
        // do not plan chunks; handle unknown/invalid size explicitly
    }
}

Type guard

strings.Contains(err.Error(), "failed extracting file size")

Try / catch

if err := d.checkTotalBytes(resp); err != nil {
    if strings.Contains(err.Error(), "failed extracting file size") {
        // log raw header, fall back to sequential download or abort
    }
}

Prevention

When it happens

Trigger: Server returns a Content-Range like 'bytes 0-99/abc' or 'bytes 0-99/12GB' where the segment after '/' is not a plain base-10 integer.

Common situations: Buggy or non-standard storage backends; a hand-written mock server; intermediate proxies rewriting Content-Range; exotic object stores with proprietary units.

Related errors


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