kopia/kopia · error
error processing snapshot
Error message
error processing snapshot %v
What it means
RewriteSnapshotManifest wraps any error from processing the snapshot's root entry via getCachedReplacement, annotated with the snapshot's ID. It means the root directory tree could not be rewritten — the failure could be anywhere in the tree (object open, child rewrite, manifest write), all aggregated here.
Solutions
- Look at the full wrapped error chain to find the offending path/object ID within the snapshot.
- Repair the repository (kopia repository repair / restore from the affected blobs) or delete/recreate the damaged snapshot.
- Set OnDirectoryReadFailure to snapshotfs.RewriteAsStub(rep) so unreadable directories are stubbed instead of failing the entire snapshot rewrite.
- Retry after resolving transient storage/network issues; the rewrite cache avoids reprocessing unchanged subtrees.
Defensive patterns
Strategy: try-catch
Validate before calling
// verify snapshot root object exists before rewriting
if _, err := rep.OpenObject(ctx, man.RootEntry.ObjectID); err != nil {
return fmt.Errorf("snapshot %d root object unreadable: %w", man.ID, err)
} Try / catch
changed, err := rw.RewriteSnapshotManifest(ctx, man, comp)
if err != nil {
log.Printf("snapshot %d rewrite failed: %+v", man.ID, err) // print full chain
// decide: skip snapshot, stub it, or abort
return false, nil
} Prevention
- Set OnDirectoryReadFailure to RewriteAsStub to keep going past damaged directories.
- Run kopia repository verify on snapshots before maintenance rewrites.
- Process snapshots one at a time so one bad snapshot doesn't abort a batch.
- Log the full error chain (%+v with pkg/errors) to locate the failing subtree.
When it happens
Trigger: rw.getCachedReplacement(ctx, ".", man.RootEntry, metadataComp) returns an error when rewriting the root entry of snapshot man.ID; e.g. root directory object unreadable, nested child failure wrapped by its name, cache get/unmarshal failure.
Common situations: Running kopia snapshot repair/migration (e.g. after compression changes or maintenance rewrite) against a repository with damaged or missing root directory objects, storage outages, or snapshot manifests referencing pruned blobs.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- <child name>
- error rewriting manifest
- a snapshot time is needed to use a path as source
- error estimating
- error getting filesystem entry for
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/ad82caaf20932393.
Report an issue: GitHub.
Appendix: source
Thrown at snapshot/snapshotfs/dir_rewriter.go:229
}
func (rw *DirRewriter) equalEntries(e1, e2 *snapshot.DirEntry) bool {
if e1 == nil {
return e2 == nil
}
if e2 == nil {
return false
}
return rw.getCacheKey(e1) == rw.getCacheKey(e2)
}
// RewriteSnapshotManifest rewrites the directory tree starting at a given manifest.
func (rw *DirRewriter) RewriteSnapshotManifest(ctx context.Context, man *snapshot.Manifest, metadataComp compression.Name) (bool, error) {
newEntry, err := rw.getCachedReplacement(ctx, ".", man.RootEntry, metadataComp)
if err != nil {
return false, errors.Wrapf(err, "error processing snapshot %v", man.ID)
}
if newEntry == nil {
newEntry, err = rw.opts.OnDirectoryReadFailure(ctx, ".", man.RootEntry, errors.Errorf("invalid root directory %v", man.ID))
if err != nil {
return false, err
}
}
if !rw.equalEntries(newEntry, man.RootEntry) {
man.RootEntry = newEntry
return true, nil
}
return false, nil
}
// Close closes the rewriter.View on GitHub (pinned to 82495e54b5)