juicedata/juicefs · error
failed to read footer length: err %w, read len %d, expect le
Error message
failed to read footer length: err %w, read len %d, expect len %d
What it means
BakFooter.Unmarshal reads the last 8 bytes of the stream to obtain the footer length. If the read errors or returns fewer bytes than requested, the file is too short or unreadable and this wrapped error is returned, preventing footer parsing.
Source
Thrown at pkg/meta/backup.go:204
if n, err := w.Write(data); err != nil && n != len(data) {
return fmt.Errorf("failed to write footer data: err %w, write len %d, expect len %d", err, n, len(data))
}
h.Len = uint64(len(data))
if n, err := w.Write(binary.BigEndian.AppendUint64(nil, h.Len)); err != nil && n != 8 {
return fmt.Errorf("failed to write footer length: err %w, write len %d, expect len 8", err, n)
}
return nil
}
func (h *BakFooter) Unmarshal(r io.ReadSeeker) error {
lenSize := int64(unsafe.Sizeof(h.Len))
_, _ = r.Seek(-lenSize, io.SeekEnd)
data := make([]byte, lenSize)
if n, err := r.Read(data); err != nil && n != int(lenSize) {
return fmt.Errorf("failed to read footer length: err %w, read len %d, expect len %d", err, n, lenSize)
}
h.Len = binary.BigEndian.Uint64(data)
_, _ = r.Seek(-int64(h.Len)-lenSize, io.SeekEnd)
data = make([]byte, h.Len)
if n, err := r.Read(data); err != nil && n != int(h.Len) {
return fmt.Errorf("failed to read footer: err %w, read len %d, expect len %d", err, n, h.Len)
}
h.Msg = &pb.Footer{}
if err := proto.Unmarshal(data, h.Msg); err != nil {
return fmt.Errorf("failed to unmarshal footer: %w", err)
}
return nil
}
type BakSegment struct {
typ uint32View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify the backup file size and integrity; re-transfer it
- Regenerate the backup with juicefs dump
- Check the source storage for read errors (dmesg, object storage consistency)
Defensive patterns
Strategy: validation
Validate before calling
fi, err := os.Stat(bakPath)
if err != nil {
return err
}
if fi.Size() < 8 {
return fmt.Errorf("%s too small to contain a footer", bakPath)
} Type guard
func plausiblyBackup(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.Size() > 8
} Try / catch
footer, err := f.ReadFooter(rs)
if err != nil {
if strings.Contains(err.Error(), "failed to read footer length") {
return fmt.Errorf("backup file truncated or unreadable: %w", err)
}
return err
} Prevention
- Verify backup file size/checksum after transfer
- Avoid partial uploads; upload only completed files
- Check storage health if tail reads fail repeatedly
When it happens
Trigger: ReadFooter → BakFooter.Unmarshal on a file smaller than 8 bytes, a truncated backup, or an unreadable/corrupt tail region (I/O error from the underlying ReadSeeker).
Common situations: Pointing summary/load at a truncated or partially uploaded backup file; a zero-byte or wrong file passed to juicefs load/summary; storage-level corruption at the file tail.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to read footer: err %w, read len %d, expect len %d
- failed to write EOS: err %w, write len %d, expect len 4
- failed to write footer data: err %w, write len %d, expect le
- failed to write footer length: err %w, write len %d, expect
- failed to write segment type %s : %w
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/038f623fe9477416.
Report an issue: GitHub.