AlistGo/alist · error

file size unknown

Error message

file size unknown

What it means

In checkTotalBytes, when the Content-Range total segment is '*' the server explicitly declines to state the total size. Because the downloader's chunk planner (d.params.Size) expects a known size, it cancels the transfer with this error. The comment in code notes the intended fallback is sequential chunking until a 416, but the current path treats unknown size as fatal when a size was expected.

Source

Thrown at internal/net/request.go:502

		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

}

func (d *downloader) incrWritten(n int64) {
	d.m.Lock()

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Use a driver/path that provides the file size (e.g. via metadata/list API) before starting the ranged download.
  2. If you operate the server, include the total length in Content-Range.
  3. For genuinely size-less sources, download sequentially without ranged chunking rather than through this downloader.
  4. Clear stale cached metadata if the size was cached as -1/unknown.
Defensive patterns

Strategy: fallback

Validate before calling

parts := strings.Split(contentRange, "/")
if parts[len(parts)-1] == "*" {
    // size unknown: choose sequential download path, skip chunk planner
}

Type guard

strings.Contains(err.Error(), "file size unknown")

Try / catch

if err := d.checkTotalBytes(resp); err != nil {
    if strings.Contains(err.Error(), "file size unknown") {
        // fall back to sequential read-until-416 / single-stream download
    }
}

Prevention

When it happens

Trigger: Ranged GET response with 'Content-Range: bytes 0-1023/*' — server supports ranges but not total reporting; some object stores and CDNs do this for dynamically generated or streamed content.

Common situations: Downloading from a storage driver whose server omits totals; pre-signed URLs that hide object size; streaming endpoints.

Related errors


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