kopia/kopia · warning

operation supported only on direct repository

Error message

operation supported only on direct repository

What it means

attemptReadPackFileLocalIndex reads a section of a pack blob that supposedly contains the pack-local index, using sm.st.GetBlob with the pack file ID, offset and length. If GetBlob fails, the error is wrapped as "error getting blob %v" naming the pack file. This is the optimized-read path that tries to use each pack's embedded local index before falling back to the shared index.

Solutions

  1. Retry the operation — callers (readPackFileLocalIndex) fall back to the non-optimized index path, so transient errors are usually harmless.
  2. Check that the pack blob exists in the storage backend and that connectivity/credentials are valid.
  3. Run kopia maintenance (compact + garbage collection) to reconcile index state with actual blobs.

Example fix

// before
if err := readPackFileLocalIndex(ctx, packFile); err != nil {
	return err // optimized-read failure aborts
}
// after
if err := readPackFileLocalIndex(ctx, packFile); err != nil {
	log.Debugf("optimized local-index read failed for %v: %v; falling back", packFile, err)
	return loadFromSharedIndex(ctx, packFile) // graceful fallback
}
Defensive patterns

Strategy: fallback

Try / catch

if err := readPackFileLocalIndex(ctx, packFile); err != nil {
	// optimized path is best-effort: log and fall back to shared index
	log.Debugf("local index read failed: %v", err)
	return sm.loadFromSharedIndex(ctx, packFile)
}

Prevention

When it happens

Trigger: readPackFileLocalIndex attempts the optimized path for a pack file whose blob cannot be fetched: blob missing from storage, network/backend error, or insufficient permissions during GetBlob(packFile, offset, length).

Common situations: Pack file garbage-collected or deleted by maintenance in another client; transient S3/network failure; eventually-consistent backend not yet showing a newly uploaded pack; corrupted provider credentials.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at cli/app.go:428

		}

		return c.runAppWithContext(kpc.SelectedCommand, func(ctx context.Context) error {
			return act(ctx, apiClient)
		})
	}
}

func assertDirectRepository(act func(ctx context.Context, rep repo.DirectRepository) error) func(ctx context.Context, rep repo.Repository) error {
	return func(ctx context.Context, rep repo.Repository) error {
		if rep == nil {
			return act(ctx, nil)
		}

		// right now this assertion never fails,
		// but will fail in the future when we have remote repository implementation
		lr, ok := rep.(repo.DirectRepository)
		if !ok {
			return errors.New("operation supported only on direct repository")
		}

		return act(ctx, lr)
	}
}

func (c *App) directRepositoryWriteAction(act func(ctx context.Context, rep repo.DirectRepositoryWriter) error) func(ctx *kingpin.ParseContext) error {
	return c.repositoryAction(assertDirectRepository(func(ctx context.Context, rep repo.DirectRepository) error {
		rep.LogManager().Enable()

		return repo.DirectWriteSession(ctx, rep, repo.WriteSessionOptions{
			Purpose:  "cli:" + c.currentActionName(),
			OnUpload: c.progress.UploadedBytes,
		}, act)
	}))
}

func (c *App) directRepositoryReadAction(act func(ctx context.Context, rep repo.DirectRepository) error) func(ctx *kingpin.ParseContext) error {

View on GitHub (pinned to 82495e54b5)