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

  1. Ensure the source bucket is shut down and immutable before calling PrependSegmentsFromBucket (the documented precondition)
  2. Free disk space on the target volume or restore to a volume with room for the full segment set
  3. 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

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.