lingochamp/FileDownloader · error · IOException

Create parent directory failed, please make sure you have…

Error message

Create parent directory failed, please make sure you have permission to create file or directory on the path: %s

What it means

DownloadTaskHunter.prepare() throws IOException when the parent directory of the target path does not exist and mkdirs() fails to create it. This is a filesystem/permission problem on the device (e.g. unmounted external storage or missing WRITE_EXTERNAL_STORAGE).

Solutions

  1. Request WRITE_EXTERNAL_STORAGE (or use app-scoped storage like context.getExternalFilesDir(null)) at runtime.
  2. Check File.canWrite() / Environment.getExternalStorageState() before creating the task.
  3. Download to a directory that already exists or your app's private directory.
  4. Catch IOException around start/queue set usage and surface a user-facing message.

Example fix

// before
FileDownloader.getImpl().create(url, "/sdcard/mydir/file.zip");

// after
File dir = new File(context.getExternalFilesDir(null), "mydir");
if (!dir.exists()) dir.mkdirs();
if (!dir.canWrite()) throw new IOException("dir not writable");
FileDownloader.getImpl().create(url, new File(dir, "file.zip").getAbsolutePath());
Defensive patterns

Strategy: try-catch

Validate before calling

File dir = new File(FileDownloadUtils.getParent(path));
if (!dir.exists() && !dir.mkdirs()) throw new IOException("cannot create " + dir);
if (!dir.canWrite()) throw new IOException("not writable: " + dir);

Try / catch

try { task.start(); } catch (IOException e) { requestStoragePermissionOrFallbackDir(); }

Prevention

When it happens

Trigger: Target path under a directory that cannot be created: external storage unmounted, no storage permission, or path on read-only volume.

Common situations: Android 6.0+ without runtime WRITE_EXTERNAL_STORAGE permission; saving to /sdcard/... on scoped-storage Android 10+; storage removed mid-session.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08). Data as JSON: /api/errors/7ec28ec3f2512514. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/DownloadTaskHunter.java:552

            }
        }

        final File dir;
        if (origin.isPathAsDirectory()) {
            dir = new File(origin.getPath());
        } else {
            final String dirString = FileDownloadUtils.getParent(origin.getPath());
            if (dirString == null) {
                throw new InvalidParameterException(
                        FileDownloadUtils.formatString("the provided mPath[%s] is invalid,"
                                + " can't find its directory", origin.getPath()));
            }
            dir = new File(dirString);
        }

        if (!dir.exists()) {
            if (!dir.mkdirs() && !dir.exists()) {
                throw new IOException(FileDownloadUtils.
                        formatString("Create parent directory failed, please make sure "
                                        + "you have permission to create file or directory "
                                        + "on the path: %s",
                                dir.getAbsolutePath()));
            }
        }
    }

    private int getId() {
        return mTask.getRunningTask().getOrigin().getId();
    }

    @SuppressWarnings("checkstyle:emptyblock")
    @Override
    public void start() {
        if (mStatus != FileDownloadStatus.toLaunchPool) {
            FileDownloadLog.w(this, "High concurrent cause, this task %d will not start,"
                            + " because the of status isn't toLaunchPool: %d",

View on GitHub (pinned to 6237a8cac1)