{"record":{"id":"2528caf62cc2eab1","repo":"juicedata/juicefs","slug":"failed-to-write-footer-data-err-w-write-len-d","errorCode":null,"errorMessage":"failed to write footer data: err %w, write len %d, expect len %d","messagePattern":"failed to write footer data: err %w, write len (.+?), expect len (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/backup.go","lineNumber":188,"sourceCode":"\t\treturn nil, fmt.Errorf(\"invalid magic number %d, expect %d\", footer.Msg.Magic, BakMagic)\n\t}\n\tf.Footer = footer\n\treturn footer, nil\n}\n\ntype BakFooter struct {\n\tMsg *pb.Footer\n\tLen uint64\n}\n\nfunc (h *BakFooter) Marshal(w io.Writer) error {\n\tdata, err := proto.Marshal(h.Msg)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal footer: %w\", err)\n\t}\n\n\tif n, err := w.Write(data); err != nil && n != len(data) {\n\t\treturn fmt.Errorf(\"failed to write footer data: err %w, write len %d, expect len %d\", err, n, len(data))\n\t}\n\n\th.Len = uint64(len(data))\n\tif n, err := w.Write(binary.BigEndian.AppendUint64(nil, h.Len)); err != nil && n != 8 {\n\t\treturn fmt.Errorf(\"failed to write footer length: err %w, write len %d, expect len 8\", err, n)\n\t}\n\treturn nil\n}\n\nfunc (h *BakFooter) Unmarshal(r io.ReadSeeker) error {\n\tlenSize := int64(unsafe.Sizeof(h.Len))\n\t_, _ = r.Seek(-lenSize, io.SeekEnd)\n\n\tdata := make([]byte, lenSize)\n\tif n, err := r.Read(data); err != nil && n != int(lenSize) {\n\t\treturn fmt.Errorf(\"failed to read footer length: err %w, read len %d, expect len %d\", err, n, lenSize)\n\t}\n","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/backup.go#L170-L206","documentation":"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.","triggerScenarios":"writeFooter → BakFooter.Marshal when the destination writer fails: disk full, closed network connection, pipe reader gone, or io.ErrShortWrite from a custom writer wrapper.","commonSituations":"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.","solutions":["Check destination free space/quota and re-run the dump","Dump to a local file first, then upload, to avoid mid-stream network failures","Verify proxy/timeout settings if streaming to remote storage"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure output location is writable with headroom\nif err := unix.Access(destDir, unix.W_OK); err != nil { return err }","typeGuard":null,"tryCatchPattern":"if err := f.writeFooter(w); err != nil {\n    if strings.Contains(err.Error(), \"failed to write footer data\") {\n        return fmt.Errorf(\"destination write failed (disk full / broken stream): %w\", err)\n    }\n    return err\n}","preventionTips":["Check disk space before large dumps","Dump to local storage, upload afterwards","Monitor pipe consumers so they don't exit early"],"tags":["backup","io","write","short-write"],"backgroundTag":"file-write-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}