benbjohnson/litestream · error
cannot determine L%d max ltx file for %q: %w
Error message
cannot determine L%d max ltx file for %q: %w
What it means
Wraps a failure from Replica.MaxLTXFileInfo when determining the maximum LTX file at a given level for the database, used to populate the maxLTXFileInfos cache. It is thrown when neither cached nor locally-known info exists and the remote max-file lookup fails.
Source
Thrown at db.go:3288
return 0, exec.pos, err
}
return h.Sum64(), exec.pos, nil
}
// MaxLTXFileInfo returns the metadata for the last LTX file in a level.
// If cached, it will returned the local copy. Otherwise, it fetches from the replica.
func (db *DB) MaxLTXFileInfo(ctx context.Context, level int) (ltx.FileInfo, error) {
db.maxLTXFileInfos.Lock()
defer db.maxLTXFileInfos.Unlock()
info, ok := db.maxLTXFileInfos.m[level]
if ok {
return *info, nil
}
remoteInfo, err := db.Replica.MaxLTXFileInfo(ctx, level)
if err != nil {
return ltx.FileInfo{}, fmt.Errorf("cannot determine L%d max ltx file for %q: %w", level, db.Path(), err)
}
db.maxLTXFileInfos.m[level] = &remoteInfo
return remoteInfo, nil
}
// DefaultRestoreParallelism is the default parallelism when downloading WAL files.
const DefaultRestoreParallelism = 8
// DefaultFollowInterval is the default polling interval for follow mode.
const DefaultFollowInterval = 1 * time.Second
// IntegrityCheckMode specifies the level of integrity checking after restore.
type IntegrityCheckMode int
const (
IntegrityCheckNone IntegrityCheckMode = iota
IntegrityCheckQuickView on GitHub (pinned to 4ed7a308f6)
Solutions
- Check the wrapped inner error to separate auth, network, and not-found causes.
- Verify the replica URL (bucket, path, region/endpoint) in the litestream config.
- Confirm credentials have ListBucket/Get permissions on the prefix.
- Retry after transient failures; the lookup is read-only and cached on success.
- If the bucket is intentionally empty, ensure the caller tolerates a zero TXID rather than erroring.
Example fix
// before
remoteInfo, err := db.Replica.MaxLTXFileInfo(ctx, level)
if err != nil { return ltx.FileInfo{}, fmt.Errorf("cannot determine L%d max ltx file for %q: %w", level, db.Path(), err) }
// after (pre-flight init)
if err := db.Replica.Client.Init(ctx); err != nil { return ltx.FileInfo{}, fmt.Errorf("init replica: %w", err) }
remoteInfo, err := db.Replica.MaxLTXFileInfo(ctx, level)
if err != nil { return ltx.FileInfo{}, fmt.Errorf("cannot determine L%d max ltx file for %q: %w", level, db.Path(), err) } Defensive patterns
Strategy: retry
Validate before calling
if err := db.Replica.Client.Init(ctx); err != nil { return fmt.Errorf("replica init failed: %w", err) } Try / catch
info, err := db.Replica.MaxLTXFileInfo(ctx, level)
if err != nil {
if isTransient(err) { return retryWithBackoff(ctx) }
return fmt.Errorf("cannot determine L%d max ltx file: %w", level, err)
} Prevention
- Verify the replica URL before first sync.
- Ensure list/get permissions on the bucket prefix.
- Handle the empty-bucket case explicitly instead of treating it as failure.
When it happens
Trigger: Operations needing the latest remote LTX file at a level (restore position checks, compaction decisions) when MaxLTXFileInfo's listing fails: storage outage, auth failure, or an unreachable/misnamed bucket (db.go:3288).
Common situations: First sync against a freshly configured replica with wrong credentials; network partition during compaction; typo'd bucket or path in the config.
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
- replica sync: %w
- fetch ltx files: %w
- write ltx file: %w
- list level %d ltx files: %w
- close level %d ltx iterator: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/2742c014dbf65b91.
Report an issue: GitHub.