juicedata/juicefs · error

failed to write footer length: err %w, write len %d, expect

Error message

failed to write footer length: err %w, write len %d, expect len 8

What it means

BakFooter.Marshal finishes by writing the 8-byte big-endian footer length. If the writer errors or writes fewer than 8 bytes, the footer (and thus the backup) is malformed and unreadable, so this wrapped error is returned.

Source

Thrown at pkg/meta/backup.go:193

type BakFooter struct {
	Msg *pb.Footer
	Len uint64
}

func (h *BakFooter) Marshal(w io.Writer) error {
	data, err := proto.Marshal(h.Msg)
	if err != nil {
		return fmt.Errorf("failed to marshal footer: %w", err)
	}

	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)

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Free space on the destination and re-run the dump
  2. Write the backup to a local file, then transfer it separately
  3. Check network stability/timeouts for streamed dumps
Defensive patterns

Strategy: retry

Try / catch

if err := f.writeFooter(w); err != nil {
    if strings.Contains(err.Error(), "failed to write footer length") {
        return fmt.Errorf("backup truncated at footer; retry dump: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: writeFooter → BakFooter.Marshal on the final length write when the destination stream fails: disk full, connection closed, or a short-write from a wrapped writer.

Common situations: Dumping to a full or quota-limited volume; streaming over an interrupted network connection; consumer of a pipe terminating before the dump completes.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/9964394569defe24. Report an issue: GitHub.