benbjohnson/litestream · error
created at: %w
Error message
created at: %w
What it means
CalcRestoreTarget computes the time range covered by backups so a restore target time can be validated. This error wraps a failure from r.TimeBounds(ctx), which enumerates LTX files to derive createdAt/updatedAt. If deriving the current (v0.5.x LTX) time bounds fails, restore target calculation aborts with this message.
Source
Thrown at replica.go:566
createdAt = info.CreatedAt
}
if updatedAt.IsZero() || info.CreatedAt.After(updatedAt) {
updatedAt = info.CreatedAt
}
}
if err := itr.Close(); err != nil {
return createdAt, updatedAt, err
}
}
return createdAt, updatedAt, nil
}
// CalcRestoreTarget returns a target time restore from.
func (r *Replica) CalcRestoreTarget(ctx context.Context, opt RestoreOptions) (updatedAt time.Time, err error) {
// Determine the replicated time bounds from LTX files.
createdAt, updatedAt, err := r.TimeBounds(ctx)
if err != nil {
return time.Time{}, fmt.Errorf("created at: %w", err)
}
// Also check v0.3.x time bounds if client supports it.
if client, ok := r.Client.(ReplicaClientV3); ok {
v3CreatedAt, v3UpdatedAt, err := r.TimeBoundsV3(ctx, client)
if err != nil {
return time.Time{}, fmt.Errorf("v0.3.x time bounds: %w", err)
}
// Extend time bounds to include v0.3.x backups.
if !v3CreatedAt.IsZero() && (createdAt.IsZero() || v3CreatedAt.Before(createdAt)) {
createdAt = v3CreatedAt
}
if !v3UpdatedAt.IsZero() && (updatedAt.IsZero() || v3UpdatedAt.After(updatedAt)) {
updatedAt = v3UpdatedAt
}
}
// Skip if it does not contain timestamp.View on GitHub (pinned to 4ed7a308f6)
Solutions
- Inspect the wrapped cause from TimeBounds to find whether listing or header parsing failed.
- Verify the replica bucket/prefix contains valid LTX files (inspect with `litestream ltx`).
- Remove or re-replicate corrupted/truncated LTX objects, or run `litestream reset` locally and let a full sync re-upload.
- Check storage credentials and connectivity if listing itself fails.
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure replica has readable LTX objects before computing a restore target
_, err := replica.CalcRestoreTarget(ctx, litestream.RestoreOptions{})
// an empty-timestamp call surfaces time-bound errors early Try / catch
target, err := replica.CalcRestoreTarget(ctx, opt)
if err != nil && strings.Contains(err.Error(), "created at") {
// time-bound enumeration failed: inspect wrapped cause, validate LTX objects
} Prevention
- Inspect replicas with `litestream ltx` to catch corrupt objects early
- Avoid manual edits/deletions inside the replica storage prefix
- Ensure uploads complete atomically so no truncated LTX files persist
When it happens
Trigger: Calling Replica.CalcRestoreTarget when r.TimeBounds fails — e.g. listing LTX files in storage errors, or a listed LTX file's metadata cannot be read/parsed (corrupt header, truncated object).
Common situations: Corrupted or manually modified LTX objects in storage; partial uploads from a previous crash; storage backend returning errors during listing; wrong bucket/prefix configured so unexpected objects are read.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/2f1497c30b8f278b.
Report an issue: GitHub.