{"record":{"id":"67b80ef63549d34a","repo":"juicedata/juicefs","slug":"writeend-s-s","errorCode":null,"errorMessage":"writeend %s: %s","messagePattern":"writeend (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/mdtest.go","lineNumber":84,"sourceCode":"\tm := jfs.Meta()\n\tfor i := 0; i < files; i++ {\n\t\tfn := path.Join(root, fmt.Sprintf(\"file.mdtest.%d.%d\", np, i))\n\t\tf, err := jfs.Create(ctx, fn, 0666, umask)\n\t\tif err != 0 {\n\t\t\treturn fmt.Errorf(\"create %s: %s\", fn, err)\n\t\t}\n\t\tif bytes > 0 {\n\t\t\tfor indx := 0; indx*meta.ChunkSize < bytes; indx++ {\n\t\t\t\tvar id uint64\n\t\t\t\tif st := m.NewSlice(ctx, &id); st != 0 {\n\t\t\t\t\treturn fmt.Errorf(\"writechunk %s: %s\", fn, st)\n\t\t\t\t}\n\t\t\t\tsize := meta.ChunkSize\n\t\t\t\tif bytes < (indx+1)*meta.ChunkSize {\n\t\t\t\t\tsize = bytes - indx*meta.ChunkSize\n\t\t\t\t}\n\t\t\t\tif st := m.Write(ctx, f.Inode(), uint32(indx), 0, meta.Slice{Id: id, Size: uint32(size), Len: uint32(size)}, time.Now()); st != 0 {\n\t\t\t\t\treturn fmt.Errorf(\"writeend %s: %s\", fn, st)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tf.Close(ctx)\n\t\tbar.Increment()\n\t}\n\tif d > 0 {\n\t\tdirs := make([]int, width)\n\t\tfor i := 0; i < width; i++ {\n\t\t\tdirs[i] = i\n\t\t}\n\t\trand.Shuffle(width, func(i, j int) {\n\t\t\tdirs[i], dirs[j] = dirs[j], dirs[i]\n\t\t})\n\t\tfor i := range dirs {\n\t\t\tdn := path.Join(root, fmt.Sprintf(\"mdtest_tree.%d\", dirs[i]))\n\t\t\tif err := createFile(jfs, bar, np, dn, d-1, width, files, bytes); err != nil {\n\t\t\t\treturn err","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/mdtest.go#L66-L102","documentation":"Reported when m.Write() — which persists a filled slice into the file's chunk index in the metadata engine — returns a non-zero errno. After NewSlice allocates an ID, mdtest bypasses the normal write path and calls meta.Write directly to register the slice at chunk index `indx`; a failure here means the metadata engine rejected the chunk-index update. Shown as `writeend <file>: <errno>` when running with -write > 0.","triggerScenarios":"`juicefs mdtest -write N` where the meta backend fails on the chunk write/persist step: session lost or revoked (EINVAL/EPERM on stale session), backend write error, timeout, or quota enforcement rejecting the write for the inode.","commonSituations":"Long-running mdtest where the client session expires mid-write; metadata backend restart or failover during the run; Redis async replication lagging/failing under write load; SQL backend connection pool exhausted under many threads.","solutions":["Check backend logs at the failure timestamp for the specific errno cause (connection, timeout, quota)","Ensure session stability — avoid restarting the meta backend during mdtest; re-run after it recovers","Reduce --threads and file count to lower write pressure on the metadata engine","Confirm no quota is exceeded on the volume (`juicefs quota` / info) since quota denial fails Write","Retry with the same command once backend health is confirmed; errors here are mostly transient backend issues"],"exampleFix":"// before\n// mdtest run continues against a restarting Redis -> writeend file.mdtest.0.3: connection refused\n// after\n// wait for backend healthy, then\n$ juicefs mdtest --threads 8 -write 1048576 redis://localhost /t","handlingStrategy":"retry","validationCode":"// confirm session alive and no quota exceeded before write phase\nif err := m.Ping(meta.Background()); err != 0 {\n    logger.Fatalf(\"session/backend unhealthy: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"// treat errno as transient and re-run or retry the write\nif st := m.Write(ctx, f.Inode(), uint32(indx), 0, sl, time.Now()); st != 0 {\n    if isTransient(st) { // EIO/EAGAIN/conn errors\n        time.Sleep(retryBackoff)\n        continue\n    }\n    return fmt.Errorf(\"writeend %s: %s\", fn, st)\n}","preventionTips":["Don't restart or fail over the meta backend mid-benchmark","Check volume quotas before write-heavy runs","Keep sessions alive; avoid client idle timeouts on long runs","Monitor backend error rates and stop the benchmark when they spike"],"tags":["metadata","write","chunk","mdtest"],"backgroundTag":"database-write-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}