juicedata/juicefs · error

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

Error message

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

What it means

After protobuf-serializing the footer, BakFooter.Marshal writes the serialized bytes and fails when the io.Writer errors or returns a short write (n != len(data)). The backup stream is therefore incomplete and the dump must be retried.

Source

Thrown at pkg/meta/backup.go:188

		return nil, fmt.Errorf("invalid magic number %d, expect %d", footer.Msg.Magic, BakMagic)
	}
	f.Footer = footer
	return footer, nil
}

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)
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check destination free space/quota and re-run the dump
  2. Dump to a local file first, then upload, to avoid mid-stream network failures
  3. Verify proxy/timeout settings if streaming to remote storage
Defensive patterns

Strategy: retry

Validate before calling

// ensure output location is writable with headroom
if err := unix.Access(destDir, unix.W_OK); err != nil { return err }

Try / catch

if err := f.writeFooter(w); err != nil {
    if strings.Contains(err.Error(), "failed to write footer data") {
        return fmt.Errorf("destination write failed (disk full / broken stream): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: writeFooter → BakFooter.Marshal when the destination writer fails: disk full, closed network connection, pipe reader gone, or io.ErrShortWrite from a custom writer wrapper.

Common situations: Dumping metadata directly to an S3/HTTP stream that was cut off; output filesystem out of space; piping dump output to a consumer that exited early.

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/2528caf62cc2eab1. Report an issue: GitHub.