{"record":{"id":"f6dfc7ebfde8552d","repo":"VictoriaMetrics/VictoriaMetrics","slug":"wrong-data-size-uploaded-to-q-at-s-got-d-bytes","errorCode":null,"errorMessage":"wrong data size uploaded to %q at %s; got %d bytes; want %d bytes","messagePattern":"wrong data size uploaded to %q at (.+?); got (.+?) bytes; want (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/backup/gcsremote/gcs.go","lineNumber":215,"sourceCode":"\treturn nil\n}\n\n// UploadPart uploads part p from r to fs.\nfunc (fs *FS) UploadPart(p common.Part, r io.Reader) error {\n\to := fs.object(p)\n\tw := o.NewWriter(fs.ctx)\n\tif len(fs.Metadata) > 0 {\n\t\tw.Metadata = fs.Metadata\n\t}\n\tn, err := io.Copy(w, r)\n\tif err1 := w.Close(); err1 != nil && err == nil {\n\t\terr = err1\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot upload data to %q at %s (remote path %q): %w\", p.Path, fs, o.ObjectName(), err)\n\t}\n\tif uint64(n) != p.Size {\n\t\treturn fmt.Errorf(\"wrong data size uploaded to %q at %s; got %d bytes; want %d bytes\", p.Path, fs, n, p.Size)\n\t}\n\treturn nil\n}\n\nfunc (fs *FS) object(p common.Part) *storage.ObjectHandle {\n\tpath := p.RemotePath(fs.Dir)\n\treturn fs.bkt.Object(path)\n}\n\n// DeleteFile deletes filePath at fs if it exists.\n//\n// The function does nothing if the filePath doesn't exists.\nfunc (fs *FS) DeleteFile(filePath string) error {\n\tpath := path.Join(fs.Dir, filePath)\n\treturn fs.delete(path)\n}\n\nfunc (fs *FS) delete(path string) error {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/backup/gcsremote/gcs.go#L197-L233","documentation":"UploadPart verifies that the number of bytes read from r (and handed to the GCS writer) equals the expected part size p.Size. A mismatch means the uploaded object will not match the backup manifest, so the upload is treated as failed. This protects against truncated or over-long source data corrupting the backup.","triggerScenarios":"io.Copy returned n != p.Size — the reader r produced fewer bytes than declared (e.g. the local part file was truncated/modified after metadata was computed) or more bytes than expected (source data changed mid-upload).","commonSituations":"Local data files being modified while the backup runs (no snapshot/quiesce); corrupted local part files; stale part metadata from a previous run; disk errors while reading the source file.","solutions":["Ensure the origin data is not modified during the backup (stop writes or use fsfreeze/snapshot).","Re-run the backup so p.Size is recomputed against current data.","Check the source part file integrity (size, filesystem errors) and re-create it if truncated.","Delete the bad remote object and re-upload the part."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fi, err := os.Open(partPath)\nif err != nil {\n    return err\n}\ninfo, _ := fi.Stat()\nif uint64(info.Size()) != p.Size {\n    return fmt.Errorf(\"local part size %d != expected %d; re-run backup\", info.Size(), p.Size)\n}","typeGuard":null,"tryCatchPattern":"if err := fs.UploadPart(p, r); err != nil {\n    if strings.Contains(err.Error(), \"wrong data size uploaded\") {\n        // source data changed mid-backup; quiesce writes and re-run\n    }\n}","preventionTips":["Quiesce or snapshot origin data before backing up","Verify local part file sizes against metadata before upload","Recompute part metadata on every backup run instead of caching"],"tags":["gcs","upload","size-mismatch","data-integrity"],"backgroundTag":"size-mismatch-after-upload","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}