juicedata/juicefs · error
failed to read footer length: err
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.
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
- failed to read segment
- failed to read segment type
- failed to read segment value: err
- failed to write EOS: err
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/038f623fe9477416.
Report an issue: GitHub.
Appendix: 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)