lingochamp/FileDownloader · error · IOException

Can't delete the old file

Error message

Can't delete the old file([%s], [%d]), so can't replace it with the new downloaded one.

What it means

Thrown by DownloadStatusCallback.renameTempFile (reached from handleCompleted) when the download finished and the target file already exists, but deleting the old target file fails. Since the completed temp file cannot replace an undeletable old file, the finalization fails and the task is marked errored. Typical causes are the file being locked/held open by another process, or filesystem permission problems.

Solutions

  1. Ensure no other process/thread keeps the target file open so it can be deleted (close streams, release file locks).
  2. Verify the app has write/delete permission on the target directory and file.
  3. Delete or rename the stale target file manually before retrying the download.
  4. Catch the IOException in the error callback and retry the download, ideally to a different target path.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at library/src/main/java/com/liulishuo/filedownloader/download/DownloadStatusCallback.java:302 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/download/DownloadStatusCallback.java:302

        model.setStatus(FileDownloadStatus.error);

        database.remove(id);
        database.removeConnections(id);
    }

    private void renameTempFile() throws IOException {
        final String tempPath = model.getTempFilePath();
        final String targetPath = model.getTargetFilePath();

        final File tempFile = new File(tempPath);
        boolean renameFailed = true;
        try {
            final File targetFile = new File(targetPath);

            if (targetFile.exists()) {
                final long oldTargetFileLength = targetFile.length();
                if (!targetFile.delete()) {
                    throw new IOException(FileDownloadUtils.formatString(
                            "Can't delete the old file([%s], [%d]), "
                                    + "so can't replace it with the new downloaded one.",
                            targetPath, oldTargetFileLength
                    ));
                } else {
                    FileDownloadLog.w(this, "The target file([%s], [%d]) will be replaced with"
                                    + " the new downloaded file[%d]",
                            targetPath, oldTargetFileLength, tempFile.length());
                }
            }

            renameFailed = !tempFile.renameTo(targetFile);
            if (renameFailed) {
                throw new IOException(FileDownloadUtils.formatString(
                        "Can't rename the  temp downloaded file(%s) to the target file(%s)",
                        tempPath, targetPath
                ));
            }

View on GitHub (pinned to 6237a8cac1)