{"record":{"id":"1b5e15919de91675","repo":"juicedata/juicefs","slug":"write","errorCode":null,"errorMessage":"write","messagePattern":"write","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java","lineNumber":1322,"sourceCode":"      int r = lib.jfs_fsync(Thread.currentThread().getId(), fd);\n      if (r == EINVAL)\n        throw new IOException(\"stream was closed\");\n      if (r < 0)\n        throw error(r, path);\n    }\n\n    @Override\n    public void write(byte[] b, int off, int len) throws IOException {\n      if (b.length - off < len) {\n        throw new IndexOutOfBoundsException();\n      }\n      int done = lib.jfs_write(Thread.currentThread().getId(), fd, ByteBuffer.wrap(b, off, len), len);\n      if (done == EINVAL)\n        throw new IOException(\"stream was closed\");\n      if (done < 0)\n        throw error(done, path);\n      if (done < len) {\n        throw new IOException(\"write\");\n      }\n    }\n\n    @Override\n    public void write(int b) throws IOException {\n      int done = lib.jfs_write(Thread.currentThread().getId(), fd, ByteBuffer.wrap(new byte[]{(byte) b}), 1);\n      if (done == EINVAL)\n        throw new IOException(\"stream was closed\");\n      if (done < 0)\n        throw error(done, path);\n      if (done < 1)\n        throw new IOException(\"write\");\n    }\n  }\n\n  static class BufferedFSOutputStream extends BufferedOutputStream implements Syncable {\n    private String hflushMethod;\n    private boolean closed;","sourceCodeStart":1304,"sourceCodeEnd":1340,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java#L1304-L1340","documentation":"FSOutputStream.write(byte[], int, int) calls the native jfs_write through JNI. If the native call returns a non-negative value smaller than the requested length, the library throws a plain IOException(\"write\") because a partial write means the underlying JuiceFS writer did not accept all bytes and data would otherwise be silently lost.","triggerScenarios":"Calling OutputStream.write(byte[], off, len) (directly or through a buffering wrapper flushing to the FSOutputStream) when the native layer accepts fewer bytes than requested — e.g. the write-back cache failed to enqueue the data or an internal native-side error caused a short write.","commonSituations":"Copying files with FileSystem.copyFromLocalFile or IOUtils.copyBytes into JuiceFS when the native client hits an internal buffer limit; writing large byte arrays whose length exceeds the native chunk writer capacity; native library memory pressure.","solutions":["Check the native client logs (juicefs mount/java-sdk log) for the underlying write error preceding the short write","Retrying the write on a fresh stream: close the stream, re-create the file with overwrite and re-write the data","Verify the JNI library version matches the juicefs version (mixing versions can cause misbehaving jfs_write)","Buffer writes into chunks <= a few MB rather than one very large array"],"exampleFix":"// before\nout.write(hugeBuffer); // may throw IOException(\"write\") on short write\n// after\nint off = 0;\nwhile (off < hugeBuffer.length) {\n  int chunk = Math.min(4 * 1024 * 1024, hugeBuffer.length - off);\n  out.write(hugeBuffer, off, chunk);\n  off += chunk;\n}","handlingStrategy":"try-catch","validationCode":"if (b == null || off < 0 || len < 0 || b.length - off < len) throw new IllegalArgumentException(\"bad write buffer bounds\");","typeGuard":null,"tryCatchPattern":"try {\n  out.write(buf, off, len);\n} catch (IOException e) {\n  if (\"write\".equals(e.getMessage())) {\n    // short write: recreate stream and retry\n    recreateAndRewrite(file, buf, off, len);\n  } else throw e;\n}","preventionTips":["Write in bounded chunks (a few MB) instead of one huge array","Check native client logs alongside the Java stack trace for the root cause","Keep the JNI native library version aligned with the juicefs release","Wrap writes in retry logic that reopens the file on failure"],"tags":["java","io","jni","write-failed"],"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-14T00:17:10.932Z"}