{"record":{"id":"2516e363a1676c99","repo":"kopia/kopia","slug":"error-loading-write-epoch","errorCode":null,"errorMessage":"error loading write epoch","messagePattern":"error loading write epoch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/epoch/epoch_manager.go","lineNumber":499,"sourceCode":"\n\tfor err := e.refreshAttemptLocked(ctx); err != nil; err = e.refreshAttemptLocked(ctx) {\n\t\tif ctx.Err() != nil {\n\t\t\treturn errors.Wrap(ctx.Err(), \"refreshAttemptLocked\")\n\t\t}\n\n\t\tcontentlog.Log2(ctx, e.log, \"refresh attempt failed\", logparam.Error(\"error\", err), logparam.Duration(\"nextDelayTime\", nextDelayTime))\n\t\ttime.Sleep(nextDelayTime)\n\n\t\tnextDelayTime = min(time.Duration(float64(nextDelayTime)*maxRefreshAttemptSleepExponent), maxRefreshAttemptSleep)\n\t}\n\n\treturn nil\n}\n\nfunc (e *Manager) loadWriteEpoch(ctx context.Context, cs *CurrentSnapshot) error {\n\tblobs, err := blob.ListAllBlobs(ctx, e.st, EpochMarkerIndexBlobPrefix)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error loading write epoch\")\n\t}\n\n\tfor epoch, bm := range groupByEpochNumber(blobs) {\n\t\tcs.EpochStartTime[epoch] = bm[0].Timestamp\n\n\t\tif epoch > cs.WriteEpoch {\n\t\t\tcs.WriteEpoch = epoch\n\t\t}\n\t}\n\n\tcs.EpochMarkerBlobs = blobs\n\n\treturn nil\n}\n\nfunc (e *Manager) loadDeletionWatermark(ctx context.Context, cs *CurrentSnapshot) error {\n\tblobs, err := blob.ListAllBlobs(ctx, e.st, DeletionWatermarkBlobPrefix)\n\tif err != nil {","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/epoch/epoch_manager.go#L481-L517","documentation":"loadWriteEpoch wraps a failure from blob.ListAllBlobs when enumerating epoch marker index blobs (EpochMarkerIndexBlobPrefix) to rebuild the CurrentSnapshot's write epoch state. Without listing these blobs the manager cannot determine the current write epoch or per-epoch start times, so snapshot loading fails.","triggerScenarios":"Calling verifyCurrentWriteEpoch (or snapshot load via the anonymous caller) when the underlying blob storage returns an error listing blobs under the EpochMarkerIndex prefix — storage outage, permission failure, malformed store response.","commonSituations":"Blob store connectivity loss or expired credentials during node startup; bucket/container missing or renamed after migration; storage backend returning throttling/5xx errors that ListAllBlobs does not absorb.","solutions":["Fix the wrapped storage error: verify blob store connectivity, credentials, and that the epoch marker index container/prefix exists.","Confirm the storage prefix EpochMarkerIndexBlobPrefix matches where epoch markers were actually written (no version/migration drift).","Retry snapshot loading — transient list failures clear once the backend recovers.","Check storage backend quotas/throttling if the error is rate limiting."],"exampleFix":"// before: fail startup hard on transient list error\nif err := mgr.loadWriteEpoch(ctx, snapshot); err != nil { return err }\n\n// after: brief retry for transient storage errors\nerr := mgr.loadWriteEpoch(ctx, snapshot)\nif err != nil && isTransientStorage(err) {\n    time.Sleep(2 * time.Second)\n    err = mgr.loadWriteEpoch(ctx, snapshot)\n}","handlingStrategy":"retry","validationCode":"// probe storage before snapshot load\nif _, err := blob.ListAllBlobs(ctx, st, EpochMarkerIndexBlobPrefix); err != nil {\n    return fmt.Errorf(\"epoch marker index not listable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := mgr.loadWriteEpoch(ctx, snapshot); err != nil {\n    if strings.Contains(err.Error(), \"error loading write epoch\") {\n        // storage list failure: check blob store health/credentials, retry after backoff\n    }\n    return err\n}","preventionTips":["Verify blob store connectivity and credentials before node startup.","Ensure the epoch marker index prefix/container exists in every environment.","Monitor storage backend for throttling and quota exhaustion.","Retry transient list errors during snapshot load with capped backoff."],"tags":["blob-storage","epoch-manager","list-failed","storage"],"backgroundTag":"database-query-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"}