flipped-aurora/gin-vue-admin · error
整文件校验失败
Error message
整文件校验失败
What it means
After MergeChunks concatenates all chunks into merged.bin and returns its MD5, Complete() compares gotMd5 with the FileHash recorded at session creation. A mismatch returns '整文件校验失败' (whole-file verification failed) via fail(), which also marks the upload failed.
Source
Thrown at server/service/media/media_upload.go:140
global.GVA_DB.WithContext(ctx).Model(&media.MediaUpload{}).Where("id = ?", uploadID).Update("status", media.UploadStatusFailed)
return m, e
}
// 校验分片齐全
var cnt int64
global.GVA_DB.WithContext(ctx).Model(&media.MediaUploadChunk{}).Where("upload_id = ?", uploadID).Count(&cnt)
if int(cnt) != up.ChunkTotal {
return fail(fmt.Errorf("分片不全: %d/%d", cnt, up.ChunkTotal))
}
// 合并到临时成品
merged := filepath.Join(upload.ChunkDir(uploadID), "merged.bin")
gotMd5, err := upload.MergeChunks(uploadID, up.ChunkTotal, merged)
if err != nil {
return fail(err)
}
if gotMd5 != up.FileHash {
return fail(errors.New("整文件校验失败"))
}
// 经 OSS 接口推到配置存储
fh, cleanup, err := upload.BuildFileHeader(merged, "file", up.FileName)
if err != nil {
return fail(err)
}
defer cleanup()
oss := upload.NewOss()
url, key, err := oss.UploadFile(ctx, fh)
if err != nil {
return fail(err)
}
// 登记媒体库
ext := ""
if i := strings.LastIndex(up.FileName, "."); i >= 0 {
ext = strings.TrimPrefix(up.FileName[i:], ".")View on GitHub (pinned to 3136500ef3)
Solutions
- Verify the client's pre-computed hash matches the exact file being chunked (same bytes, same algorithm — MD5 here).
- Re-upload the file: create a fresh upload session, re-hash, upload all chunks, then Complete.
- Check chunk-level integrity: ensure every chunk uploaded successfully and indexes are correct before calling Complete.
- Confirm no process modified merged.bin or the chunk dir between uploads and merge.
- Enable per-chunk hash verification on upload to localize the corrupt chunk.
Example fix
// before: hashing before the user finalizes file selection
const hash = await md5(await pickFile()) // file may change afterwards
// after: hash the exact final bytes right before upload
const file = await pickFile()
const hash = await md5(file) // hash the same File object being chunked
await api.initUpload({ fileName: file.name, fileHash: hash, chunkTotal }) Defensive patterns
Strategy: validation
Validate before calling
// client-side: verify all chunks uploaded and hash the exact final bytes
const hash = await md5(file)
const allUploaded = chunkResults.every(r => r.ok)
if (!allUploaded) throw new Error('some chunks failed; do not call Complete')
if (!hash || hash.length !== 32) throw new Error('invalid md5 hash') Try / catch
try {
await svc.Complete(ctx, userID, uploadID)
} catch (err) {
if (err.Error() === '整文件校验失败') {
// discard session and re-upload with a freshly computed hash
} else {
throw err
}
} Prevention
- Hash the exact file object being chunked, right before upload
- Use the same hash algorithm (MD5) the server expects
- Verify every chunk upload response before calling Complete
- Prevent file modification between hashing and upload completion
When it happens
Trigger: Any chunk was corrupted in transit/storage, a chunk is missing or duplicated, the client-supplied FileHash at Init does not match the actual file bytes, or the file was modified after hashing (client re-generated the file without restarting the session).
Common situations: Client computes MD5 of a different file version than the chunks uploaded; chunk upload retried with wrong index order; disk/storage corruption; user edited the file mid-upload; hash algorithm mismatch (MD5 vs SHA256) between client and server.
Related errors
- 分片 %d 校验失败
- 分片不全: %d/%d
- 上传不在可合并状态(可能已在合并或已完成)
- invalid plugin archive name
- function file.Open() failed, err:
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/81ddeaeefadd0452.
Report an issue: GitHub.