bumptech/glide · error · IllegalStateException

Failed to create cache directory: {}

Error message

Failed to create cache directory: {}

What it means

Thrown by JournaledLruDiskCache.openIfNotOpen() when the cache directory cannot be created or verified. mkdirs() must succeed OR the path must already exist as a directory; if neither holds, the cache cannot be opened.

Source

Thrown at integration/sqljournaldiskcache/src/main/java/com/bumptech/glide/integration/sqljournaldiskcache/JournaledLruDiskCache.java:130

    recoveryManager = new RecoveryManager(this, cacheDirectory, journal, workLooper);
  }

  private static Looper getBackgroundLooper() {
    HandlerThread workThread =
        new HandlerThread("disk_cache_journal", Process.THREAD_PRIORITY_BACKGROUND);
    workThread.start();
    return workThread.getLooper();
  }

  @SuppressWarnings("checkstyle:UnnecessaryParentheses") // Readability
  private void openIfNotOpen() {
    if (!isOpen) {
      synchronized (this) {
        if (!isOpen) {
          boolean createdDirectory =
              cacheDirectory.mkdirs() || (cacheDirectory.exists() && cacheDirectory.isDirectory());
          if (!createdDirectory) {
            throw new IllegalStateException("Failed to create cache directory: " + cacheDirectory);
          }
          journal.open();
          isOpen = true;
          recoveryManager.triggerRecovery();
        }
      }
    }
  }

  // TODO(judds): rather than polling, we should use Android's FileObserver.
  private void verifyCanaryOrClear() {
    if (fileSystem.exists(canaryFile)) {
      return;
    }

    synchronized (this) {
      if (fileSystem.exists(canaryFile)) {
        return;

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Use context.getCacheDir() or context.getCodeCacheDir() for app-private reliable storage.
  2. Verify the directory path is writable and that no regular file occupies it.
  3. Request the appropriate storage permission, or migrate to app-specific scoped-storage paths.
  4. Ensure external storage is mounted (Environment.getExternalStorageState()) before using external paths.
  5. Catch the exception and fall back to a different cache location or disable disk caching.

Example fix

// before
val dir = File(Environment.getExternalStorageDirectory(), "glide_cache")
// may fail: permissions / scoped storage

// after
val dir = context.cacheDir.resolve("glide_cache") // app-private, always writable
Defensive patterns

Strategy: validation

Validate before calling

// Validate the cache directory before constructing the cache.
fun safeCacheDir(context: Context, name: String): File {
  val dir = File(context.cacheDir, name)
  if (!dir.exists() && !dir.mkdirs()) {
    throw IllegalStateException("Cannot create cache dir: $dir")
  }
  check(dir.isDirectory) { "Cache path is not a directory: $dir" }
  check(dir.canWrite()) { "Cache dir not writable: $dir" }
  return dir
}

Try / catch

try {
  diskCache.open()
} catch (e: IllegalStateException) {
  if (e.message?.contains("Failed to create cache directory") == true) {
    // fall back to app-private cache dir or disable disk caching
    useFallbackCacheDir(context)
  } else throw e
}

Prevention

When it happens

Trigger: cacheDirectory.mkdirs() returns false and (cacheDirectory.exists() is false or cacheDirectory.isDirectory() is false). Causes include missing filesystem permissions, a non-directory file occupying the path, or read-only storage.

Common situations: App lacks WRITE_EXTERNAL_STORAGE on older Android versions for the chosen path; a file (not directory) exists at the cache path; the path points to private external storage not yet mounted; security/SAF restrictions on scoped storage; parent directory does not exist and mkdirs fails.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/7c7778cc68c96882. Report an issue: GitHub.