benbjohnson/litestream · error

fetch header: %w

Error message

fetch header: %w

What it means

After merging page indexes in rebuildIndex, the VFS calls FetchLTXHeader for the latest LTX file to obtain the commit header (page size, commit count). A failure downloading or decoding that header is wrapped as "fetch header: %w". Without a valid commit header the rebuilt index cannot be installed.

Source

Thrown at vfs.go:1355

	index := make(map[uint32]ltx.PageIndexElem)
	var commit uint32
	for _, info := range infos {
		f.logger.Debug("opening page index", "level", info.Level, "min", info.MinTXID, "max", info.MaxTXID)

		// Read page index.
		idx, err := FetchPageIndex(ctx, f.client, info)
		if err != nil {
			return nil, fmt.Errorf("fetch page index: %w", err)
		}

		// Replace pages in overall index with new pages.
		for k, v := range idx {
			f.logger.Debug("adding page index", "page", k, "elem", v)
			index[k] = v
		}
		hdr, err := FetchLTXHeader(ctx, f.client, info)
		if err != nil {
			return nil, fmt.Errorf("fetch header: %w", err)
		}
		commit = hdr.Commit
	}

	f.mu.Lock()
	f.commit = commit
	f.mu.Unlock()

	return index, nil
}

// buildIndex constructs a lookup of pgno to LTX file offsets (legacy wrapper).
func (f *VFSFile) buildIndex(ctx context.Context, infos []*ltx.FileInfo) error {
	return f.rebuildIndex(ctx, infos, nil)
}

// initHydration starts the background hydration process.
func (f *VFSFile) initHydration(infos []*ltx.FileInfo) error {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Inspect the wrapped error to identify transport vs. format failure.
  2. Retry the rebuild; transient storage errors frequently clear.
  3. Validate the newest LTX with `litestream ltx -level all`; re-replicate if corrupt.
  4. Ensure the litestream version writing LTX files matches the version reading them.
Defensive patterns

Strategy: retry

Try / catch

if err := file.ResetTime(ctx); err != nil {
    var se *storeError
    if errors.As(err, &se) && isTransient(se.Unwrap()) {
        time.Sleep(backoff)
        err = file.ResetTime(ctx)
    }
}

Prevention

When it happens

Trigger: ResetTime/time-travel rebuild reaching FetchLTXHeader when the LTX object is missing, truncated, corrupt, or the replica client returns a transport error; also when the latest LTX file was replaced/deleted between planning and fetch.

Common situations: Object-store outages or throttling (S3 503 SlowDown); truncated uploads from a killed litestream process; LTX format/version mismatch between client and stored files; credentials revoked mid-operation.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/37b7a16b4f0de7c0. Report an issue: GitHub.