{"record":{"id":"23e529859bc67bd8","repo":"elastic/elasticsearch","slug":"error","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":"NoSuchFileException","httpStatus":null,"severity":"error","filePath":"libs/core/src/main/java/org/elasticsearch/core/IOUtils.java","lineNumber":293,"sourceCode":"    }\n\n    /**\n     * Ensure that any writes to the given file is written to the storage device that contains it. The {@code isDir} parameter specifies\n     * whether or not the path to sync is a directory. This is needed because we open for read and ignore an {@link IOException} since not\n     * all filesystems and operating systems support fsyncing on a directory. For regular files we must open for write for the fsync to have\n     * an effect.\n     *\n     * @param fileToSync the file to fsync\n     * @param isDir      if true, the given file is a directory (we open for read and ignore {@link IOException}s, because not all file\n     *                   systems and operating systems allow to fsync on a directory)\n     * @param metaData   if {@code true} both the file's content and metadata will be sync, otherwise only the file's content will be sync\n     */\n    public static void fsync(final Path fileToSync, final boolean isDir, final boolean metaData) throws IOException {\n        if (isDir && WINDOWS) {\n            // opening a directory on Windows fails, directories can not be fsynced there\n            if (Files.exists(fileToSync) == false) {\n                // yet do not suppress trying to fsync directories that do not exist\n                throw new NoSuchFileException(fileToSync.toString());\n            }\n            return;\n        }\n        try (FileChannel file = FileChannel.open(fileToSync, isDir ? StandardOpenOption.READ : StandardOpenOption.WRITE)) {\n            try {\n                file.force(metaData);\n            } catch (final IOException e) {\n                if (isDir) {\n                    assert (LINUX || MAC_OS_X) == false\n                        : \"on Linux and MacOSX fsyncing a directory should not throw IOException, \"\n                            + \"we just don't want to rely on that in production (undocumented); got: \"\n                            + e;\n                    // ignore exception if it is a directory\n                    return;\n                }\n                // throw original exception\n                throw e;\n            }","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/core/IOUtils.java#L275-L311","documentation":"Thrown as a NoSuchFileException by IOUtils.fsync when, on Windows, the caller asserts isDir=true but the directory does not exist. Windows cannot open a directory for fsync, so the method short-circuits — but not before verifying the directory exists, since silently ignoring a missing directory would hide real bugs. For non-existent regular files the channel open will fail with the standard NoSuchFileException from the filesystem.","triggerScenarios":"Calling IOUtils.fsync(path, true /*isDir*/, ...) on Windows where `path` does not exist or was deleted before the call. Also reachable when isDir=false and the file does not exist (via FileChannel.open throwing NoSuchFileException).","commonSituations":"A shutdown/recovery path that fsyncs a data directory after it was concurrently removed. Test cleanup racing with a durability flush. A configurable path that the user pointed at a non-existent directory. Windows-only CI exposing a bug hidden on Linux, where directory fsync exceptions are swallowed.","solutions":["Ensure the directory exists before fsyncing it (create it with Files.createDirectories first).","If the directory is optional, check Files.exists(path) before calling and skip when absent — but only if that is semantically safe.","On the recovery path, order operations so the directory is created before the first fsync.","Investigate concurrent deletion: a missing directory mid-recovery often indicates a race with cleanup."],"exampleFix":"// before\nIOUtils.fsync(dir, true); // throws if dir absent\n\n// after\nFiles.createDirectories(dir);\nIOUtils.fsync(dir, true);","handlingStrategy":"validation","validationCode":"// Ensure a directory exists before fsyncing it\nstatic void fsyncDir(Path dir) throws IOException {\n    if (!Files.exists(dir)) Files.createDirectories(dir);\n    IOUtils.fsync(dir, true);\n}","typeGuard":"static boolean isFsyncableDir(Path dir) {\n    return Files.isDirectory(dir); // implies exists\n}","tryCatchPattern":"try {\n    IOUtils.fsync(dir, true);\n} catch (NoSuchFileException e) {\n    // create and retry once; if still failing, surface as a recovery error\n    Files.createDirectories(dir);\n    IOUtils.fsync(dir, true);\n}","preventionTips":["Create directories with Files.createDirectories before the first fsync.","Order recovery paths so directory creation precedes fsync.","On Windows CI, test the missing-directory case explicitly.","If a directory may legitimately be absent, guard with Files.exists before fsync."],"tags":["io","filesystem","fsync","windows","durability","elasticsearch-core"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}