benbjohnson/litestream · error
invalid v0.3.x WAL segment filename: %q
Error message
invalid v0.3.x WAL segment filename: %q
What it means
ParseWALSegmentFilenameV3 extracts the WAL index and byte offset from a v0.3.x segment filename of the form '{index:08x}_{offset:08x}.wal.lz4' (e.g. '00000000_00001000.wal.lz4'). This error is returned when the filename does not match walSegmentRegexV3 at all. Litestream throws it when scanning v0.3.x replica WAL directories and encountering a name that is not a valid v0.3.x WAL segment.
Source
Thrown at v3.go:134
// Returns an error if the filename does not match the expected format.
func ParseSnapshotFilenameV3(filename string) (index int, err error) {
m := snapshotRegexV3.FindStringSubmatch(filename)
if m == nil {
return 0, fmt.Errorf("invalid v0.3.x snapshot filename: %q", filename)
}
idx, err := strconv.ParseInt(m[1], 16, 32)
if err != nil {
return 0, fmt.Errorf("invalid snapshot path: %s: %w", filename, err)
}
return int(idx), nil
}
// ParseWALSegmentFilenameV3 parses a v0.3.x WAL segment filename.
// Returns the WAL index and byte offset, or an error if the filename is invalid.
func ParseWALSegmentFilenameV3(filename string) (index int, offset int64, err error) {
m := walSegmentRegexV3.FindStringSubmatch(filename)
if m == nil {
return 0, 0, fmt.Errorf("invalid v0.3.x WAL segment filename: %q", filename)
}
idx, err := strconv.ParseInt(m[1], 16, 32)
if err != nil {
return 0, 0, fmt.Errorf("invalid wal segment path: %s: %w", filename, err)
}
off, err := strconv.ParseInt(m[2], 16, 64)
if err != nil {
return 0, 0, fmt.Errorf("invalid wal segment path: %s: %w", filename, err)
}
return int(idx), off, nil
}
// IsGenerationIDV3 returns true if s is a valid v0.3.x generation ID (16 hex chars).
func IsGenerationIDV3(s string) bool {
return generationRegexV3.MatchString(s)
}
// ReplicaClientV3 reads v0.3.x backup data.View on GitHub (pinned to 4ed7a308f6)
Solutions
- Pass only the base filename: apply filepath.Base() before parsing.
- Verify the name matches '{index:08x}_{offset:08x}.wal.lz4'; skip files that don't when scanning directories.
- For files written by Litestream v0.5+ (LTX format), use the LTX APIs, not the V3 parser.
- Confirm the file is not a checkpoint or temporary file placed inside the wal/ directory.
Example fix
// before idx, off, err := litestream.ParseWALSegmentFilenameV3(key) // key = "gen/wal/00000000_00001000.wal.lz4" // after idx, off, err := litestream.ParseWALSegmentFilenameV3(filepath.Base(key))
Defensive patterns
Strategy: validation
Validate before calling
var walSegReV3 = regexp.MustCompile(`^[0-9a-f]{8}_[0-9a-f]{8}\.wal\.lz4$`)
func isValidWALSegmentFilenameV3(name string) bool { return walSegReV3.MatchString(filepath.Base(name)) } Type guard
func isV3WALSegmentName(s string) bool { return walSegReV3.MatchString(filepath.Base(s)) }
if isV3WALSegmentName(key) { idx, off, err := litestream.ParseWALSegmentFilenameV3(filepath.Base(key)) } Try / catch
idx, off, err := litestream.ParseWALSegmentFilenameV3(filepath.Base(name))
if err != nil {
log.Printf("skipping %q: not a v0.3.x WAL segment: %v", name, err)
continue
} Prevention
- Pass the bare filename (filepath.Base), not the full replica key
- Filter directory listings to *.wal.lz4 files before parsing
- Use litestream.FormatWALSegmentFilenameV3 to generate names so they always round-trip
- Keep v0.3.x and LTX-era files in separate code paths
When it happens
Trigger: Calling ParseWALSegmentFilenameV3 with a non-conforming filename: an LTX-era '.wal' or '.ltx' name, a snapshot filename, a name with the wrong separator (e.g. '-' instead of '_'), a full path instead of the bare filename, or a truncated/corrupted name.
Common situations: Custom restore tooling iterating objects in a v0.3.x bucket's wal/ directory; mixing files from different Litestream versions in one directory; passing object keys with 'generations/<gen>/wal/' prefixes intact.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid v0.3.x snapshot filename: %q
- set synchronous: %w
- checkpoint: %w
- checkpoint failed: %w
- sync database %s: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/f26a2b5c5f4fe39c.
Report an issue: GitHub.