AlistGo/alist · error · StreamIncomplete
upload/download stream incomplete, possible network issue
Error message
upload/download stream incomplete, possible network issue
What it means
StreamIncomplete signals that a transfer stream ended prematurely — bytes actually read or written did not match the expected size, or a cloud API reported an incomplete upload. It is defined in internal/errs/errors.go and wrapped via errs.NewErr by drivers such as baidu_netdisk and baidu_youth when they verify response bodies or uploaded file sizes.
Source
Thrown at internal/errs/errors.go:20
import (
"errors"
"fmt"
pkgerr "github.com/pkg/errors"
)
var (
NotImplement = errors.New("not implement")
NotSupport = errors.New("not support")
RelativePath = errors.New("access using relative path is not allowed")
MoveBetweenTwoStorages = errors.New("can't move files between two storages, try to copy")
UploadNotSupported = errors.New("upload not supported")
MetaNotFound = errors.New("meta not found")
StorageNotFound = errors.New("storage not found")
StreamIncomplete = errors.New("upload/download stream incomplete, possible network issue")
StreamPeekFail = errors.New("StreamPeekFail")
UnknownArchiveFormat = errors.New("unknown archive format")
WrongArchivePassword = errors.New("wrong archive password")
DriverExtractNotSupported = errors.New("driver extraction not supported")
)
// NewErr wrap constant error with an extra message
// use errors.Is(err1, StorageNotFound) to check if err belongs to any internal error
func NewErr(err error, format string, a ...any) error {
return fmt.Errorf("%w; %s", err, fmt.Sprintf(format, a...))
}
func IsNotFoundError(err error) bool {
return errors.Is(pkgerr.Cause(err), ObjectNotFound) || errors.Is(pkgerr.Cause(err), StorageNotFound)
}
func IsNotSupportError(err error) bool {View on GitHub (pinned to 843d9dc814)
Solutions
- Retry the transfer (typically a transient network condition)
- Check network stability, proxy/CDN timeouts, and rate limits on the cloud provider
- Verify local disk space for TempDir when large uploads stage through temp files
- If persistent for one provider, re-authorize the storage — expired tokens sometimes produce HTML error pages that parse as truncated bodies
Example fix
// before
err := fs.Copy(ctx, src, dst, nil)
// after
err := fs.Copy(ctx, src, dst, nil)
if err != nil && errors.Is(errors.Cause(err), errs.StreamIncomplete) {
// safe to retry the copy; remove partial destination first
} Defensive patterns
Strategy: retry
Type guard
func isStreamIncomplete(err error) bool {
return err != nil && errors.Is(errors.Cause(err), errs.StreamIncomplete)
} Try / catch
err := fs.Copy(ctx, src, dst, nil)
if isStreamIncomplete(err) {
backoff.Retry(cleanPartialAndCopy, 3) // remove partial dst, then retry
} Prevention
- Wrap transfers with bounded retry + exponential backoff
- Monitor temp-dir free space
- Keep provider auth fresh — expired tokens yield HTML bodies parsed as truncation
- Retry only after cleaning partial destination files
When it happens
Trigger: Baidu netdisk driver getting a truncated/invalid response body during upload (drivers/baidu_netdisk/driver.go:454); baidu_youth detecting temp-file size mismatch between bytes written and the stream's declared size (drivers/baidu_youth/driver.go:287); baidu_youth util receiving a short error body (drivers/baidu_youth/util.go:572). In general, dropped connections mid-copy between AList and the remote storage.
Common situations: Unstable network or proxy timeouts on large uploads; remote provider throttling or resetting connections; disk full so the temp file is truncated; copy/move between two storages where the download side stalls. Transient — usually resolves on retry.
Related errors
- stopped after 10 redirects
- upload failed: %w
- upload request failed: %w
- failed to create direct link: %w
- failed to read response body: %v
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/24b01e44120b19bd.
Report an issue: GitHub.