{"record":{"id":"7aaf400eb722444c","repo":"kopia/kopia","slug":"unable-to-open-file","errorCode":null,"errorMessage":"unable to open file","messagePattern":"unable to open file","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"snapshot/upload/upload.go","lineNumber":240,"sourceCode":"\t}\n\n\tresultObject, err := rep.ConcatenateObjects(ctx, objectIDs, repo.ConcatenateOptions{Compressor: metadataComp})\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"concatenate\")\n\t}\n\n\tde := parts[0]\n\tde.Name = name\n\tde.FileSize = totalSize\n\tde.ObjectID = resultObject\n\n\treturn de, nil\n}\n\nfunc (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) {\n\tfile, err := f.Open(ctx)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to open file\")\n\t}\n\tdefer file.Close() //nolint:errcheck\n\n\twriter := u.repo.NewObjectWriter(ctx, object.WriterOptions{\n\t\tDescription:        \"FILE:\" + fname,\n\t\tCompressor:         compressor,\n\t\tMetadataCompressor: metadataComp,\n\t\tSplitter:           splitterName,\n\t\tAsyncWrites:        1, // upload chunk in parallel to writing another chunk\n\t})\n\tdefer writer.Close() //nolint:errcheck\n\n\tparentCheckpointRegistry.addCheckpointCallback(fname, func() (*snapshot.DirEntry, error) {\n\t\tcheckpointID, err := writer.Checkpoint()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"checkpoint error\")\n\t\t}\n","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/snapshot/upload/upload.go#L222-L258","documentation":"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.","triggerScenarios":"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.","commonSituations":"Files changing between directory scan and upload (TOCTOU); permission-restricted files; broken symlinks or unreadable mount points; files removed by another process mid-snapshot.","solutions":["Re-run the snapshot; transient races often resolve on retry","Exclude unreadable/changing paths from the snapshot policy","Check file permissions and ownership for the kopia process","Ensure the source filesystem is mounted and the file exists"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check readability before uploading\nif fi, err := os.Stat(path); err != nil || fi == nil {\n\treturn fmt.Errorf(\"source %q not readable at upload time\", path)\n}\nif f, err := os.Open(path); err != nil {\n\treturn fmt.Errorf(\"cannot open %q: %w\", path, err)\n} else {\n\tf.Close()\n}","typeGuard":null,"tryCatchPattern":"_, err := uploader.Upload(ctx, sourcePath)\nvar pe *fs.PathError\nif err != nil && stderrors.As(err, &pe) {\n\tlog.Warnf(\"skipping unreadable file: %v\", pe)\n\t// continue with the rest of the snapshot\n}","preventionTips":["Don't mutate or delete files while a snapshot is in progress","Run the uploader with permissions covering all source files","Exclude volatile paths (caches, sockets) from the policy","Re-run snapshots after racing writes"],"tags":["upload","filesystem","file-open"],"backgroundTag":"file-open-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}