google/ExoPlayer · error · IOException
Couldn't create {baseName}
Error message
Couldn't create {baseName} What it means
Thrown by AtomicFile.startWrite() when opening the base file for output raises FileNotFoundException and either the file has no parent directory or parent.mkdirs() fails to create it. AtomicFile implements write-then-rename atomic persistence (used for example by StandaloneMediaClock/DownloadManager/DatabaseProvider caches), and this error means it cannot even obtain a writable target file. Typical causes are missing storage permissions, a parent path that exists as a regular file, or read-only/missing external storage.
Source
Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/AtomicFile.java:116
*/
public OutputStream startWrite() throws IOException {
// Rename the current file so it may be used as a backup during the next read
if (baseName.exists()) {
if (!backupName.exists()) {
if (!baseName.renameTo(backupName)) {
Log.w(TAG, "Couldn't rename file " + baseName + " to backup file " + backupName);
}
} else {
baseName.delete();
}
}
OutputStream str;
try {
str = new AtomicFileOutputStream(baseName);
} catch (FileNotFoundException e) {
File parent = baseName.getParentFile();
if (parent == null || !parent.mkdirs()) {
throw new IOException("Couldn't create " + baseName, e);
}
// Try again now that we've created the parent directory.
try {
str = new AtomicFileOutputStream(baseName);
} catch (FileNotFoundException e2) {
throw new IOException("Couldn't create " + baseName, e2);
}
}
return str;
}
/**
* Call when you have successfully finished writing to the stream returned by {@link
* #startWrite()}. This will close, sync, and commit the new data. The next attempt to read the
* atomic file will return the new file stream.
*
* @param str Outer-most wrapper OutputStream used to write to the stream returned by {@link
* #startWrite()}.View on GitHub (pinned to dd430f7053)
Solutions
- Check and request the correct storage permission (WRITE_EXTERNAL_STORAGE pre-API 30, or use app-private Context.getFilesDir()/getCacheDir() which needs no permission)
- Verify the parent directory: ensure no regular file exists at the parent path, then call parent.mkdirs() yourself and log File.getCanonicalPath() and canWrite() before startWrite()
- Use context-qualified paths (context.filesDir, context.cacheDir, or MediaStore API for shared storage) instead of hardcoded /sdcard paths
- Free space / re-mount storage and retry the write once the environment check passes
Example fix
// before
AtomicFile file = new AtomicFile(new File("/sdcard/myapp/state.bin"));
OutputStream os = file.startWrite(); // may throw IOException
// after
File dir = new File(context.getFilesDir(), "state");
if (!dir.exists() && !dir.mkdirs()) throw new IOException("Cannot mkdirs " + dir);
AtomicFile file = new AtomicFile(new File(dir, "state.bin"));
OutputStream os = file.startWrite(); Defensive patterns
Strategy: validation
Validate before calling
File dir = baseFile.getParentFile();
if (dir == null || (!dir.exists() && !dir.mkdirs()) || !dir.canWrite()) {
// pick app-private storage or fail early with a clear message
} Try / catch
catch (IOException e) { Log.w(TAG, "Cannot persist state to " + file, e); /* fall back to in-memory state */ } Prevention
- Always build AtomicFile paths under Context.getFilesDir()/getCacheDir()
- Run canWrite() and a StatFs free-space check before startWrite()
- Keep a last-known-good copy: AtomicFile's .new/.bak mechanics only help if you finishWrite() successfully
When it happens
Trigger: Calling AtomicFile.startWrite() where baseName's parent directory does not exist and mkdirs() returns false: parent path occupied by a regular file, no WRITE permission for the location, external storage unmounted (path like /storage/emulated/0/... unavailable), or disk full/quota enforcing mkdir failure.
Common situations: App targeting API 30+ without properly scoped storage access writing to a shared directory; device USB-unmounted sdcard; the cache/data directory wiped or made read-only; path built from an environment variable (getExternalStorageDirectory) that is stale on newer Android versions.
Related errors
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/4bef0d5816b50a49.
Report an issue: GitHub.