weaviate/weaviate · error
prepend segments: copy files: %w
Error message
prepend segments: copy files: %w
What it means
copySegmentFiles failed while copying segment files from srcDir into the target directory with the timestamp shift applied. The wrapped cause can be an error finding associated files (index 2149), parsing the timestamp, opening/creating files, copying, fsyncing, or renaming the staged .tmp files. Copied state is cleaned up so no partial segments remain staged without .tmp handling.
Source
Thrown at adapters/repos/db/lsmkv/segment_group_prepend.go:116
}
defer func() {
// Best-effort resume — if this fails, the segment group's compaction
// stays paused, which is degraded but not data-losing.
_ = sg.resumeCompaction(ctx)
}()
// Step 3: Compute timestamp shift and copy files with crash-safe staging.
tgtDBFiles, err := discoverDBFiles(sg.dir)
if err != nil {
return fmt.Errorf("prepend segments: discover target segments: %w", err)
}
shift, err := computeTimestampShift(srcDBFiles, tgtDBFiles)
if err != nil {
return fmt.Errorf("prepend segments: compute timestamp shift: %w", err)
}
copiedDBPaths, err := copySegmentFiles(srcDir, sg.dir, srcDBFiles, shift)
if err != nil {
return fmt.Errorf("prepend segments: copy files: %w", err)
}
// Step 4: Initialize segments from the copied .db files.
initialized, err := sg.initPrependedSegments(copiedDBPaths)
if err != nil {
// Clean up copied files on failure.
cleanupCopiedFiles(sg.dir, copiedDBPaths)
return fmt.Errorf("prepend segments: init segments: %w", err)
}
// Step 5: Atomic prepend under maintenanceLock.
func() {
sg.maintenanceLock.Lock()
defer sg.maintenanceLock.Unlock()
newSegments := make([]Segment, 0, len(initialized)+len(sg.segments))
newSegments = append(newSegments, initialized...)
newSegments = append(newSegments, sg.segments...)View on GitHub (pinned to 75aa4b6d11)
Solutions
- Ensure the source bucket is shut down and immutable before calling PrependSegmentsFromBucket (the documented precondition)
- Free disk space on the target volume or restore to a volume with room for the full segment set
- Re-run after fixing permissions; failed copies are cleaned up so the operation is safely retryable
Example fix
// before go bucket.Close() err := sg.PrependSegmentsFromBucket(ctx, srcDir) // src mutated mid-copy if not closed // after srcBucket.Shutdown(ctx) // guarantee source immutability err = sg.PrependSegmentsFromBucket(ctx, srcDir)
Defensive patterns
Strategy: try-catch
Validate before calling
// check free space and source immutability up front
var st syscall.Statfs_t
syscall.Statfs(dstDir, &st)
if uint64(st.Bavail)*uint64(st.Bsize) < requiredBytes {
return errors.New("insufficient disk space for prepend")
} Try / catch
if err := sg.PrependSegmentsFromBucket(ctx, srcDir); err != nil {
// copies are cleaned up; safe to retry after fixing cause
if strings.Contains(err.Error(), "copy ") || strings.Contains(err.Error(), "rename ") {
return retryWithBackoff(ctx, func() error {
return sg.PrependSegmentsFromBucket(ctx, srcDir)
})
}
return err
} Prevention
- Shut down the source bucket before prepending (documented precondition)
- Provision disk space at least equal to the source segment set size
- Retry prepends after transient IO errors; staging/cleanup makes them idempotent
When it happens
Trigger: Disk full on the target volume so copyFileWithSync's os.Create or io.Copy fails; source file removed between discovery and copy (source bucket not shut down / still compacting); rename(2) failing across filesystems or due to permissions.
Common situations: Restoring a backup onto a volume with insufficient free space; running the restore while the source bucket is live (violating the documented precondition that the source must be shut down and immutable); EACCES/EPERM from restrictive file modes.
Related errors
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/437f5997c9c0e0e8.
Report an issue: GitHub.