AlistGo/alist · error

invalid hash

Error message

invalid hash

What it means

Returned by PutRapid() in the Baidu Netdisk driver when the file stream's MD5 hash is missing or shorter than a full MD5 (32 hex chars). Rapid (instant) upload works only by presenting a complete content MD5, so a partial/absent hash aborts the operation.

Source

Thrown at drivers/baidu_netdisk/driver.go:173

			"path":    srcObj.GetPath(),
			"dest":    dstDir.GetPath(),
			"newname": srcObj.GetName(),
		},
	}
	_, err := d.manage("copy", data)
	return err
}

func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
	data := []string{obj.GetPath()}
	_, err := d.manage("delete", data)
	return err
}

func (d *BaiduNetdisk) PutRapid(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) (model.Obj, error) {
	contentMd5 := stream.GetHash().GetHash(utils.MD5)
	if len(contentMd5) < utils.MD5.Width {
		return nil, errors.New("invalid hash")
	}

	streamSize := stream.GetSize()
	path := stdpath.Join(dstDir.GetPath(), stream.GetName())
	mtime := stream.ModTime().Unix()
	ctime := stream.CreateTime().Unix()
	blockList, _ := utils.Json.MarshalToString([]string{contentMd5})

	var newFile File
	_, err := d.create(path, streamSize, 0, "", blockList, &newFile, mtime, ctime)
	if err != nil {
		return nil, err
	}
	// 修复时间,具体原因见 Put 方法注释的 **注意**
	newFile.Ctime = stream.CreateTime().Unix()
	newFile.Mtime = stream.ModTime().Unix()
	return fileToObj(newFile), nil
}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Enable MD5 hashing for the upload pipeline so the stream carries a full 32-char MD5 before PutRapid is attempted
  2. If invoking PutRapid programmatically, wrap the stream and pre-compute the MD5 (read once or hash on the fly) before calling
  3. Fall back to the normal chunked Put path when no MD5 is available instead of PutRapid

Example fix

// before
obj, err := d.PutRapid(ctx, dstDir, stream) // stream has no MD5
// after: compute hash first, or skip rapid path
if h := stream.GetHash().GetHash(utils.MD5); len(h) < utils.MD5.Width {
    return d.Put(ctx, dstDir, stream, up) // normal upload
}
Defensive patterns

Strategy: validation

Validate before calling

func canRapidUpload(s model.FileStreamer) bool {
    return len(s.GetHash().GetHash(utils.MD5)) >= utils.MD5.Width
}
if !canRapidUpload(stream) { /* use normal Put */ }

Type guard

func hasFullMD5(s model.FileStreamer) bool {\n    return len(s.GetHash().GetHash(utils.MD5)) >= utils.MD5.Width\n}

Try / catch

if _, err := d.PutRapid(ctx, dst, stream); err != nil && strings.Contains(err.Error(), "invalid hash") { err = d.Put(ctx, dst, stream, up) }

Prevention

When it happens

Trigger: Calling PutRapid with a model.FileStreamer whose hash registry has no MD5 entry (e.g. the file was not hashed before upload) or only a prefix (hashing still in progress / truncated).

Common situations: Uploading through an API/webdav path that does not compute MD5 before put; local upload setting has hash detection disabled; copying a stream whose hash was consumed or never set.

Related errors


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