weaviate/weaviate · error

create: %w

Error message

create: %w

What it means

For a regular (non-split) file in the restore archive, copyFile creates the destination with os.OpenFile(O_CREATE|O_WRONLY, header mode). This error wraps the OS open failure for that file. Note O_TRUNC is intentionally not set because restores always write into empty directories.

Source

Thrown at usecases/backup/zip.go:669

		f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, os.FileMode(h.Mode))
		if err != nil {
			return 0, fmt.Errorf("open: %w", err)
		}
		defer f.Close()

		// Use pwrite semantics (WriteAt) instead of seek+write so that
		// concurrent goroutines can safely write different parts of the
		// same file without racing on the shared file-descriptor offset.
		n, err := io.CopyN(&offsetWriter{f: f, offset: startOffset}, r, h.Size)
		if err != nil {
			return n, fmt.Errorf("copy split: %w", err)
		}
		return n, nil
	} else {
		// O_TRUNC is not needed: restores always write into empty directories.
		f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, os.FileMode(h.Mode))
		if err != nil {
			return written, fmt.Errorf("create: %w", err)
		}
		defer f.Close()
		written, err = io.Copy(f, r)
		if err != nil {
			return written, fmt.Errorf("copy: %w", err)
		}
		return written, nil
	}
}

type vFileInfo struct {
	name    string
	size    int
	modTime time.Time // TODO: get it when parsing source files
}

func (v vFileInfo) Name() string       { return v.name }
func (v vFileInfo) Size() int64        { return int64(v.size) }

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Ensure the restore destination directory exists and is writable by the Weaviate process user.
  2. Clear any leftovers from a failed prior restore and restore into a clean empty directory.
  3. Check disk space/inodes and that the filesystem is not mounted read-only (df -h, mount).
  4. Read the wrapped OS error in the message to identify the precise cause (permission denied, no space left, etc.).
  5. If using containerized Weaviate, verify the volume mount permissions map to the container's user.

Example fix

// before: destination owned by root, weaviate runs as user 1000
# docker run -v /root/backups:/backups weaviate
// after: chown the destination to the weaviate user
# chown -R 1000:1000 /var/lib/weaviate/backups
# docker run -v /var/lib/weaviate/backups:/backups weaviate
Defensive patterns

Strategy: validation

Validate before calling

if st, err := os.Stat(destPath); err != nil || !st.IsDir() {
    return fmt.Errorf("destination %s must exist as a directory", destPath)
}
probe := filepath.Join(destPath, ".write-probe")
if err := os.WriteFile(probe, nil, 0o644); err != nil {
    return fmt.Errorf("destination not writable: %w", err)
}
os.Remove(probe)

Try / catch

err := doRestore(ctx)
var perr *fs.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, os.ErrPermission) {
    // chown/chmod destination and retry
}

Prevention

When it happens

Trigger: os.OpenFile fails while extracting a regular tar entry: destination directory missing or removed, insufficient permissions on destPath, file exists with mode bits that forbid writing, read-only filesystem, or disk full preventing creation.

Common situations: Restore target volume read-only or out of space; Weaviate runs as unprivileged user lacking write access to the restore path; leftover files from an aborted previous restore with restrictive modes; SELinux/AppArmor blocking writes to the destination.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/0631b180ac7251fa. Report an issue: GitHub.