{"record":{"id":"92c3cf83bc30e48e","repo":"juicedata/juicefs","slug":"bytes-not-equal","errorCode":null,"errorMessage":"bytes not equal","messagePattern":"bytes not equal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/sync/sync.go","lineNumber":582,"sourceCode":"\tbuf := bufPool.Get().(*[]byte)\n\tdefer bufPool.Put(buf)\n\tbuf2 := bufPool.Get().(*[]byte)\n\tdefer bufPool.Put(buf2)\n\tfor left := int(length); left > 0; left -= bufferSize {\n\t\tbs := bufferSize\n\t\tif left < bufferSize {\n\t\t\tbs = left\n\t\t}\n\t\t*buf = (*buf)[:bs]\n\t\t*buf2 = (*buf2)[:bs]\n\t\tif _, err = io.ReadFull(in, *buf); err != nil {\n\t\t\treturn fmt.Errorf(\"src read: %s\", err)\n\t\t}\n\t\tif _, err = io.ReadFull(in2, *buf2); err != nil {\n\t\t\treturn fmt.Errorf(\"dest read: %s\", err)\n\t\t}\n\t\tif !bytes.Equal(*buf, *buf2) {\n\t\t\treturn fmt.Errorf(\"bytes not equal\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc compObjBinary(src, dst object.ObjectStorage, key string, abort chan struct{}, obj object.Object) (bool, error) {\n\tvar err error\n\tif obj.Size() < maxBlock {\n\t\terr = compObjPartBinary(src, dst, key, abort, 0, obj.Size())\n\t} else {\n\t\tn := int((obj.Size()-1)/defaultPartSize) + 1\n\t\terrs := make(chan error, n)\n\t\tfor i := 0; i < n; i++ {\n\t\t\tgo func(num int) {\n\t\t\t\tsz := int64(defaultPartSize)\n\t\t\t\tif num == n-1 {\n\t\t\t\t\tsz = obj.Size() - int64(num)*defaultPartSize\n\t\t\t\t}","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/sync/sync.go#L564-L600","documentation":"The byte ranges read from source and destination differ (bytes.Equal failed). This is the core signal that the destination copy does NOT match the source, produced during binary verification of every part.","triggerScenarios":"A partial or corrupted earlier copy on dst; different object versions on each side (dst updated independently); encryption/compression settings differing between endpoints causing divergent bytes; bit-level corruption.","commonSituations":"Running `juicefs sync --check-all` after an interrupted sync; two writers updating the same key independently; misconfigured sync targets pointing at stale replicas.","solutions":["Re-copy the mismatching object from src to dst to overwrite the stale/corrupt copy.","Investigate what wrote to dst independently of the sync (other jobs, lifecycle rules, manual edits).","Align encryption/compression configuration so both endpoints store comparable bytes.","Re-run verification after the re-copy to confirm the mismatch is resolved."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// cheap pre-check: sizes must match before byte comparison\nsi, _ := src.Head(ctx, key)\ndi, err := dst.Head(ctx, key)\nif err == nil && di.Size() != si.Size() {\n\treturn overwriteDst(src, dst, key)\n}","typeGuard":null,"tryCatchPattern":"if err := comparePart(...); err != nil {\n\tif err.Error() == \"bytes not equal\" {\n\t\tlogger.Warnf(\"content mismatch on %s, re-copying\", key)\n\t\treturn fullRecopy(src, dst, key)\n\t}\n\treturn err\n}","preventionTips":["Treat the error as data corruption: always re-copy the object, never skip","Keep encryption/compression settings identical across src and dst","Audit for independent writers to the destination bucket","Run periodic --check-all verification to catch drift early"],"tags":["integrity","comparison","data-mismatch"],"backgroundTag":"checksum-mismatch","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}