kopia/kopia · error

unable to open file

Error message

unable to open file

What it means

Wrapper in Uploader.uploadFileData: f.Open failed while opening the snapshot source file for reading (file disappeared or permission denied during backup), so the file's contents cannot be uploaded and its directory entry is not produced.

Solutions

  1. Re-run the snapshot; transient races often resolve on retry
  2. Exclude unreadable/changing paths from the snapshot policy
  3. Check file permissions and ownership for the kopia process
  4. Ensure the source filesystem is mounted and the file exists
Defensive patterns

Strategy: try-catch

Validate before calling

// check readability before uploading
if fi, err := os.Stat(path); err != nil || fi == nil {
	return fmt.Errorf("source %q not readable at upload time", path)
}
if f, err := os.Open(path); err != nil {
	return fmt.Errorf("cannot open %q: %w", path, err)
} else {
	f.Close()
}

Try / catch

_, err := uploader.Upload(ctx, sourcePath)
var pe *fs.PathError
if err != nil && stderrors.As(err, &pe) {
	log.Warnf("skipping unreadable file: %v", pe)
	// continue with the rest of the snapshot
}

Prevention

When it happens

Trigger: uploadFileData calling f.Open(ctx) on a file that has been deleted, renamed, or whose permissions deny reading after it was enumerated during the snapshot walk.

Common situations: Files changing between directory scan and upload (TOCTOU); permission-restricted files; broken symlinks or unreadable mount points; files removed by another process mid-snapshot.

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 kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/7aaf400eb722444c. Report an issue: GitHub.

Appendix: source

Thrown at snapshot/upload/upload.go:240

	}

	resultObject, err := rep.ConcatenateObjects(ctx, objectIDs, repo.ConcatenateOptions{Compressor: metadataComp})
	if err != nil {
		return nil, errors.Wrap(err, "concatenate")
	}

	de := parts[0]
	de.Name = name
	de.FileSize = totalSize
	de.ObjectID = resultObject

	return de, nil
}

func (u *Uploader) uploadFileData(ctx context.Context, parentCheckpointRegistry *checkpointRegistry, f fs.File, fname string, offset, length int64, compressor, metadataComp compression.Name, splitterName string) (*snapshot.DirEntry, error) {
	file, err := f.Open(ctx)
	if err != nil {
		return nil, errors.Wrap(err, "unable to open file")
	}
	defer file.Close() //nolint:errcheck

	writer := u.repo.NewObjectWriter(ctx, object.WriterOptions{
		Description:        "FILE:" + fname,
		Compressor:         compressor,
		MetadataCompressor: metadataComp,
		Splitter:           splitterName,
		AsyncWrites:        1, // upload chunk in parallel to writing another chunk
	})
	defer writer.Close() //nolint:errcheck

	parentCheckpointRegistry.addCheckpointCallback(fname, func() (*snapshot.DirEntry, error) {
		checkpointID, err := writer.Checkpoint()
		if err != nil {
			return nil, errors.Wrap(err, "checkpoint error")
		}

View on GitHub (pinned to 82495e54b5)