{"record":{"id":"4a80a94bd8e6e4c1","repo":"kopia/kopia","slug":"error-recovering-from-v","errorCode":null,"errorMessage":"error recovering from %v","messagePattern":"error recovering from (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command_index_recover.go","lineNumber":177,"sourceCode":"\t\t\t\t\t\tif ok {\n\t\t\t\t\t\t\tlog(ctx).Infof(\"Recovered %v index entries from %v/%v blobs (%.1f %%) %v remaining %v ETA\",\n\t\t\t\t\t\t\t\trecoveredContentCount.Load(),\n\t\t\t\t\t\t\t\tfinishedBlobs,\n\t\t\t\t\t\t\t\tdisc,\n\t\t\t\t\t\t\t\te.PercentComplete,\n\t\t\t\t\t\t\t\te.Remaining,\n\t\t\t\t\t\t\t\tformatTimestamp(e.EstimatedEndTime))\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog(ctx).Infof(\"Recovered %v index entries from %v blobs, estimating time remaining... (found %v blobs)\",\n\t\t\t\t\t\t\trecoveredContentCount.Load(),\n\t\t\t\t\t\t\tfinishedBlobs,\n\t\t\t\t\t\t\tdiscoveringBlobCount.Load())\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif err := c.recoverIndexFromSinglePackFile(ctx, rep, bm.BlobID, bm.Length, processedBlobCount, recoveredContentCount); err != nil {\n\t\t\t\t\treturn errors.Wrapf(err, \"error recovering from %v\", bm.BlobID)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn nil\n\t\t})\n\t}\n\n\treturn errors.Wrap(eg.Wait(), \"recovering indexes\")\n}\n\nfunc (c *commandIndexRecover) recoverIndexFromSinglePackFile(ctx context.Context, rep repo.DirectRepositoryWriter, blobID blob.ID, length int64, processedBlobCount, recoveredContentCount *atomic.Int32) error {\n\tlog(ctx).Debugf(\"recovering from %v\", blobID)\n\n\trecovered, err := rep.ContentManager().RecoverIndexFromPackBlob(ctx, blobID, length, c.commit)\n\tif err != nil {\n\t\tif c.ignoreErrors {\n\t\t\treturn nil\n\t\t}","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/cli/command_index_recover.go#L159-L195","documentation":"In the all-packs recovery path of `kopia index recover`, recoverIndexFromSinglePackFile failed for a discovered pack blob during the parallel processing loop. kopia could not read or parse that pack blob into index entries.","triggerScenarios":"Running `kopia index recover` (no explicit blob IDs) where a discovered blob fails recovery: corrupt/truncated pack blob, blob that matches a pack prefix but is not a valid pack, or transient storage read error while fetching with the blob's metadata length.","commonSituations":"Recovery after storage corruption, interrupted uploads, or accidental partial deletion; object stores returning inconsistent reads under high concurrency; mixing blobs from an old repository in the same bucket.","solutions":["Re-run recovery — transient read errors usually clear; kopia tracks already-processed blobs so it resumes quickly.","Identify the failing blob from logs and check its integrity in the storage provider (size vs metadata length).","Restore the corrupt pack blob from provider versioning/snapshots, then re-run.","Exclude foreign/stale blobs by ensuring only this repository's data lives under the bucket prefix."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := c.recoverIndexFromSinglePackFile(ctx, rep, bm.BlobID, bm.Length, processedBlobCount, recoveredContentCount); err != nil {\n    log(ctx).Warnf(\"skipping unrecoverable pack %v: %v\", bm.BlobID, err)\n    return nil // continue with remaining packs\n}","preventionTips":["Re-run recovery after transient failures; it resumes from processed blobs.","Restore corrupt packs from provider snapshots before re-running.","Keep only one repository's data per bucket/prefix.","Monitor storage consistency; investigate blobs whose size diverges from metadata length."],"tags":["recovery","pack-blob","corruption","kopia-cli"],"backgroundTag":"index-recovery-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"}