{"record":{"id":"47324bea80e0e401","repo":"java-native-access/jna","slug":"destdir-must-be-a-directory","errorCode":null,"errorMessage":"destDir must be a directory.","messagePattern":"destDir must be a directory\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java","lineNumber":3134,"sourceCode":"        }\n    }\n\n    /**\n     * Backup an encrypted file or folder without decrypting it. A file named\n     * \"bar/sample.text\" will be backed-up to \"destDir/sample.text\". A directory\n     * named \"bar\" will be backed-up to \"destDir/bar\". This method is NOT\n     * recursive. If you have an encrypted directory with encrypted files, this\n     * method must be called once for the directory, and once for each encrypted\n     * file to be backed-up.\n     *\n     * @param src\n     *         The encrypted file or directory to backup.\n     * @param destDir\n     *         The directory where the backup will be saved.\n     */\n    public static void backupEncryptedFile(File src, File destDir) {\n        if (!destDir.isDirectory()) {\n            throw new IllegalArgumentException(\"destDir must be a directory.\");\n        }\n\n        ULONG readFlag = new ULONG(0); // Open the file for export (backup)\n        ULONG writeFlag = new ULONG(CREATE_FOR_IMPORT); // Import (restore) file\n\n        if (src.isDirectory()) {\n            writeFlag.setValue(CREATE_FOR_IMPORT | CREATE_FOR_DIR);\n        }\n\n        // open encrypted file for export\n        String srcFileName = src.getAbsolutePath();\n        PointerByReference pvContext = new PointerByReference();\n        if (Advapi32.INSTANCE.OpenEncryptedFileRaw(srcFileName, readFlag,\n                pvContext) != W32Errors.ERROR_SUCCESS) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n\n        // read encrypted file","sourceCodeStart":3116,"sourceCodeEnd":3152,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java#L3116-L3152","documentation":"Advapi32Util.backupEncryptedFile(File src, File destDir) backs up an EFS-encrypted file via the Win32 OpenEncryptedFileRaw/ReadEncryptedFileRaw API, which requires a destination directory to write the backup into. If destDir does not exist or is a regular file, the method throws IllegalArgumentException('destDir must be a directory.') before starting the backup.","triggerScenarios":"Calling backupEncryptedFile with a destDir path that does not exist, points to a file instead of a directory, or is a stale path (deleted after creation).","commonSituations":"Typo'd or uncreated output folder; passing the intended output file path rather than the containing directory; running the backup before the destination mount/dir is prepared; path separator confusion on Windows.","solutions":["Create the destination directory before the call: if (!destDir.exists()) destDir.mkdirs();","Pass the parent directory (destDir) not the output file path; the method writes the backup into the directory itself.","Verify with destDir.isDirectory() and correct the path (check for typos, drive letters, UNC paths).","If destDir is a file, delete or rename it and create a directory with the same path."],"exampleFix":"// before\nAdvapi32Util.backupEncryptedFile(src, new File(\"C:\\\\backup\\\\out.dat\"));\n// after\nFile destDir = new File(\"C:\\\\backup\");\nif (!destDir.isDirectory()) {\n    destDir.mkdirs();\n}\nAdvapi32Util.backupEncryptedFile(src, destDir);","handlingStrategy":"validation","validationCode":"if (destDir == null || !destDir.isDirectory()) {\n    throw new IllegalArgumentException(\"destDir must be an existing directory: \" + destDir);\n}","typeGuard":"boolean isWritableDirectory(File dir) {\n    return dir != null && dir.isDirectory() && dir.canWrite();\n}","tryCatchPattern":"try {\n    Advapi32Util.backupEncryptedFile(src, destDir);\n} catch (IllegalArgumentException e) {\n    log.error(\"Bad destination for EFS backup: \" + e.getMessage());\n}","preventionTips":["Call destDir.mkdirs() when the directory does not exist, before the backup.","Pass the containing directory, not the intended backup file path.","Verify with destDir.isDirectory() (not exists(), which is true for files too).","Check dir.canWrite() to ensure the backup will not fail mid-write on permissions."],"tags":["windows","efs","file-backup","validation","jna"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}