{"record":{"id":"a9a2bb02090df96e","repo":"kopia/kopia","slug":"error-restoring-a9a2bb","errorCode":null,"errorMessage":"error restoring","messagePattern":"error restoring","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/server/api_restore.go","lineNumber":114,"sourceCode":"\t\topt := req.Options\n\n\t\topt.ProgressCallback = func(_ context.Context, s restore.Stats) {\n\t\t\tctrl.ReportCounters(restoreCounters(s))\n\t\t}\n\n\t\tcancelChan := make(chan struct{})\n\t\topt.Cancel = cancelChan\n\n\t\tctrl.OnCancel(func() {\n\t\t\tclose(opt.Cancel)\n\t\t})\n\n\t\tst, err := restore.Entry(ctx, rep, out, rootEntry, opt)\n\t\tif err == nil {\n\t\t\tctrl.ReportCounters(restoreCounters(st))\n\t\t}\n\n\t\treturn errors.Wrap(err, \"error restoring\")\n\t})\n\n\ttaskID := <-taskIDChan\n\n\ttask, ok := rc.srv.taskManager().GetTask(taskID)\n\tif !ok {\n\t\treturn nil, internalServerError(errors.New(\"task not found\"))\n\t}\n\n\treturn task, nil\n}\n","sourceCodeStart":96,"sourceCodeEnd":126,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/server/api_restore.go#L96-L126","documentation":"The restore API handler wraps the result of restore.Entry — which walks the snapshot tree and writes files to the output target — with this message. Any filesystem error during restore (permissions, disk full, missing source entries) or tree-read failure is surfaced as \"error restoring\".","triggerScenarios":"POST /api/v1/restore where the target directory is unwritable or full, a file listed in the snapshot no longer exists in the blob store, or the root entry cannot be read.","commonSituations":"Restoring to a path owned by another user; disk quota exceeded mid-restore; snapshot blobs pruned/GC'd before restore; special files (symlinks, devices) failing on the target OS.","solutions":["Verify the restore target path exists and is writable by the server process","Check free disk space/quota on the target volume","Confirm the snapshot's blobs are not pruned (run `kopia snapshot verify`); reduce retention prunings","Retry the restore; check server logs for the per-file error inside restore.Entry"],"exampleFix":"// before\nout := &restore.Output{} // defaults\n// after\nout := filesystem.NewOutput(targetDir, &filesystem.OutputOptions{\n    OverwriteOverwrite: true,\n    IgnorePermissionErrors: true,\n})","handlingStrategy":"try-catch","validationCode":"// pre-restore checks\nif err := os.MkdirAll(targetDir, 0o755); err != nil { return err }\nif err := snapshot.VerifySnapshot(ctx, rep, rootID); err != nil { return err }","typeGuard":null,"tryCatchPattern":"_, err := restore.Entry(ctx, rep, out, rootEntry, opt)\nif err != nil {\n    if errors.Is(err, fs.ErrPermission) {\n        // retry with adjusted output options / different target\n    } else if errors.Is(err, blob.ErrBlobNotFound) {\n        // snapshot pruned; restore from another snapshot\n    }\n}","preventionTips":["Ensure target has free space and write permission","Verify snapshot integrity before pruning blobs","Use IgnorePermissionErrors in restore output options for partial restores"],"tags":["kopia","restore","filesystem"],"backgroundTag":"file-write-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"}