kopia/kopia · error

error compacting single epoch

Error message

error compacting single epoch

What it means

Wraps a failure from epoch.Manager.MaybeCompactSingleEpoch, which compacts the content index of one eligible uncompacted epoch into a single index blob. Emitted from runTaskEpochMaintenanceQuick when single-epoch compaction fails. The wrapped inner error identifies the actual storage or index failure.

Solutions

  1. Read the wrapped root cause to distinguish read vs. write vs. commit failures.
  2. Run kopia index recover / index optimize to repair or rebuild index blobs if corruption is suspected.
  3. Ensure no concurrent maintenance jobs operate on the same repository.
  4. Retry the epoch maintenance task; it is resumable and will re-attempt the epoch.
Defensive patterns

Strategy: retry

Validate before calling

// Go: check index integrity before maintenance
if err := rep.VerifyIndex(ctx); err != nil {
    return fmt.Errorf("run 'kopia index recover' first: %w", err)
}

Try / catch

if err := runMaintenance(ctx); err != nil {
    if isTransientStorageErr(errors.RootCause(err)) {
        scheduleRetryWithBackoff()
    } else {
        alertOperator(err)
    }
}

Prevention

When it happens

Trigger: During quick epoch maintenance, MaybeCompactSingleEpoch is invoked and fails while reading the epoch's uncompacted index blobs, merging them, or writing/committing the compacted index blob.

Common situations: Corrupt or missing index blob in storage; network interruption mid-compaction; concurrent maintenance racing on the same epoch; storage quota exceeded when writing the merged index.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/5991f8412b38accb. Report an issue: GitHub.

Appendix: source

Thrown at repo/maintenance/maintenance_run.go:364

}

func runTaskEpochAdvance(ctx context.Context, em *epoch.Manager, runParams RunParameters, s *Schedule) error {
	return reportRunAndMaybeCheckContentIndex(ctx, runParams.rep, TaskEpochAdvance, s, func() (maintenancestats.Kind, error) {
		userLog(ctx).Info("Advancing epoch markers...")

		stats, err := em.MaybeAdvanceWriteEpoch(ctx)

		return stats, errors.Wrap(err, "error advancing epoch marker")
	})
}

func runTaskEpochMaintenanceQuick(ctx context.Context, em *epoch.Manager, runParams RunParameters, s *Schedule) error {
	err := reportRunAndMaybeCheckContentIndex(ctx, runParams.rep, TaskEpochCompactSingle, s, func() (maintenancestats.Kind, error) {
		userLog(ctx).Info("Compacting an eligible uncompacted epoch...")

		stats, err := em.MaybeCompactSingleEpoch(ctx)

		return stats, errors.Wrap(err, "error compacting single epoch")
	})
	if err != nil {
		return err
	}

	err = runTaskEpochAdvance(ctx, em, runParams, s)

	return errors.Wrap(err, "error to advance epoch in quick epoch maintenance task")
}

func runTaskEpochMaintenanceFull(ctx context.Context, runParams RunParameters, s *Schedule) error {
	em, hasEpochManager, emerr := runParams.rep.ContentManager().EpochManager(ctx)
	if emerr != nil {
		return errors.Wrap(emerr, "epoch manager")
	}

	if !hasEpochManager {
		return nil

View on GitHub (pinned to 82495e54b5)