AlistGo/alist · error

invalid file size

Error message

invalid file size

What it means

GuangYaPan Put rejects files with GetSize() < 0. The provider's upload-token API requires an exact content length (it is used for instant-upload matching and OSS multipart planning), so a stream of unknown size cannot be uploaded through this driver.

Source

Thrown at drivers/guangyapan/driver.go:385

	if !strings.EqualFold(strings.TrimSpace(out.Msg), "success") {
		return fmt.Errorf("copy failed: %s", strings.TrimSpace(out.Msg))
	}
	taskID := strings.TrimSpace(out.Data.TaskID)
	if taskID == "" {
		return nil
	}
	return d.waitTaskDone(ctx, taskID)
}

func (d *GuangYaPan) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) error {
	if err := d.ensureAccessToken(ctx); err != nil {
		return err
	}
	if file == nil {
		return errors.New("file is nil")
	}
	if file.GetSize() < 0 {
		return errors.New("invalid file size")
	}
	name := strings.TrimSpace(file.GetName())
	if name == "" {
		return errors.New("file name is empty")
	}

	parentID := dstDir.GetID()

	token, code, err := d.getUploadToken(ctx, parentID, name, file.GetSize())
	if err != nil {
		return err
	}
	taskID := strings.TrimSpace(token.TaskID)
	if code == 156 {
		if taskID == "" {
			return errors.New("instant upload returns empty task id")
		}
		return d.waitUploadTaskInfo(ctx, taskID)

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Buffer the stream first so its size is known, then upload (e.g. spool to a temp file)
  2. Send a correct Content-Length header from the client (avoid chunked encoding)
  3. If using the SDK, wrap the reader in a streamer constructed with the actual length

Example fix

// before: unknown-length stream -> Put fails
// after: spool to temp file to fix the size
f, _ := os.CreateTemp("", "upload-*")
io.Copy(f, src)
f.Seek(0, io.SeekStart)
stream := model.NewFileStream(&model.Obj{Name: name, Size: fi.Size()}, f)
Defensive patterns

Strategy: validation

Validate before calling

if file.GetSize() < 0 {
	return errors.New("file size unknown; provide Content-Length or spool to disk")
}
return d.Put(ctx, dstDir, file, up)

Type guard

func hasKnownSize(f model.FileStreamer) bool { return f != nil && f.GetSize() >= 0 }

Try / catch

if err := d.Put(ctx, dir, file, up); err != nil {
	if strings.Contains(err.Error(), "invalid file size") {
		spooled := spoolToTemp(file) // buffer to fix the length
		return d.Put(ctx, dir, spooled, up)
	}
	return err
}

Prevention

When it happens

Trigger: Uploading a streamer that reports a negative size — typically model.UNKNOWN_SIZE (-1) used for chunked/streaming bodies where the length is not known in advance.

Common situations: WebDAV/FTP edge clients sending chunked transfer-encoding without Content-Length; piping stdin or a pipe reader into the upload; proxies stripping content length.

Related errors


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