airbnb/lottie-android · error · IllegalStateException

There is already a cache provider!

Error message

There is already a cache provider!

What it means

Thrown by LottieConfig.Builder#setNetworkCacheDir when a cache provider has already been registered on the same Builder instance. The cacheProvider field is single-slot, so configuring a cache directory twice (or after setNetworkCacheProvider) is treated as a programming error.

Source

Thrown at lottie/src/main/java/com/airbnb/lottie/LottieConfig.java:70

    /**
     * Lottie has a default network fetching stack built on {@link java.net.HttpURLConnection}. However, if you would like to hook into your own
     * network stack for performance, caching, or analytics, you may replace the internal stack with your own.
     */
    @NonNull
    public Builder setNetworkFetcher(@NonNull LottieNetworkFetcher fetcher) {
      this.networkFetcher = fetcher;
      return this;
    }

    /**
     * Provide your own network cache directory. By default, animations will be saved in your application's cacheDir/lottie_network_cache.
     *
     * @see #setNetworkCacheProvider(LottieNetworkCacheProvider)
     */
    @NonNull
    public Builder setNetworkCacheDir(@NonNull final File file) {
      if (cacheProvider != null) {
        throw new IllegalStateException("There is already a cache provider!");
      }
      cacheProvider = new LottieNetworkCacheProvider() {
        @Override @NonNull public File getCacheDir() {
          if (!file.isDirectory()) {
            throw new IllegalArgumentException("cache file must be a directory");
          }
          return file;
        }
      };
      return this;
    }

    /**
     * Provide your own network cache provider. By default, animations will be saved in your application's cacheDir/lottie_network_cache.
     */
    @NonNull
    public Builder setNetworkCacheProvider(@NonNull final LottieNetworkCacheProvider fileCacheProvider) {
      if (cacheProvider != null) {

View on GitHub (pinned to 05ea92e903)

Solutions

  1. Ensure setNetworkCacheDir is called at most once per LottieConfig.Builder instance.
  2. If you need both behaviors, pick exactly one of setNetworkCacheDir or setNetworkCacheProvider per Builder.
  3. Build the LottieConfig in a single, idempotent initialization method (e.g. guarded by a static 'initialized' flag or a DI provider).

Example fix

// before - helper called twice
configureLottie(builder);
builder.setNetworkCacheDir(getCacheDir()); // throws: provider already set

// after - single ownership of cache configuration
public LottieConfig buildLottieConfig() {
  LottieConfig.Builder b = new LottieConfig.Builder();
  b.setNetworkCacheDir(getCacheDir());
  return b.build();
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard cache configuration with a flag
private volatile boolean lottieCacheConfigured;
public synchronized void ensureLottieConfig(File cacheDir) {
  if (lottieCacheConfigured) return;
  LottieConfig cfg = new LottieConfig.Builder()
      .setNetworkCacheDir(cacheDir)
      .build();
  Lottie.initialize(cfg);
  lottieCacheConfigured = true;
}

Prevention

When it happens

Trigger: Calling setNetworkCacheDir(file) a second time on one LottieConfig.Builder, or calling setNetworkCacheDir after setNetworkCacheProvider on the same Builder.

Common situations: Building LottieConfig in a loop or a helper that always calls setNetworkCacheDir and is invoked twice; reusing a Builder reference; migrating from setNetworkCacheDir to setNetworkCacheProvider and leaving the old call in place.

Related errors


AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14). Data as JSON: /api/errors/7bcf59de6d7d19d1. Report an issue: GitHub.