{"record":{"id":"eebfcc1109784632","repo":"bumptech/glide","slug":"filedescriptor-is-null-for-uri","errorCode":null,"errorMessage":"FileDescriptor is null for: {uri}","messagePattern":"FileDescriptor is null for: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/bumptech/glide/load/data/AssetFileDescriptorLocalUriFetcher.java","lineNumber":31,"sourceCode":"  public AssetFileDescriptorLocalUriFetcher(ContentResolver contentResolver, Uri uri) {\n    super(contentResolver, uri);\n  }\n\n  /**\n   * useMediaStoreApisIfAvailable is part of an experiment and the constructor can be removed in a\n   * future version.\n   */\n  public AssetFileDescriptorLocalUriFetcher(\n      ContentResolver contentResolver, Uri uri, boolean useMediaStoreApisIfAvailable) {\n    super(contentResolver, uri, useMediaStoreApisIfAvailable);\n  }\n\n  @Override\n  protected AssetFileDescriptor loadResource(Uri uri, ContentResolver contentResolver)\n      throws FileNotFoundException {\n    AssetFileDescriptor result = openAssetFileDescriptor(uri);\n    if (result == null) {\n      throw new FileNotFoundException(\"FileDescriptor is null for: \" + uri);\n    }\n    return result;\n  }\n\n  @Override\n  protected void close(AssetFileDescriptor data) throws IOException {\n    data.close();\n  }\n\n  @NonNull\n  @Override\n  public Class<AssetFileDescriptor> getDataClass() {\n    return AssetFileDescriptor.class;\n  }\n}\n","sourceCodeStart":13,"sourceCodeEnd":47,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/library/src/main/java/com/bumptech/glide/load/data/AssetFileDescriptorLocalUriFetcher.java#L13-L47","documentation":"AssetFileDescriptorLocalUriFetcher loads a local content Uri by calling openAssetFileDescriptor through the ContentResolver. If the resolver returns null, no file descriptor could be opened for that Uri, and Glide throws a FileNotFoundException with the Uri in the message. This typically indicates the content at the Uri does not exist or is not accessible.","triggerScenarios":"Loading a content:// Uri for a file that has been deleted. Loading a media Uri after a permissions change. The content provider backing the Uri does not support openAssetFileDescriptor for that MIME type.","commonSituations":"Loading contact photos or media store content that was removed between the time the Uri was obtained and the load attempt. Stale Uri references from saved instance state. Content provider that only implements openFileDescriptor but not openAssetFileDescriptor.","solutions":["Verify the Uri still resolves by querying the ContentResolver before attempting to load","Handle FileNotFoundException in your RequestListener#error and show a placeholder","Ensure you have the necessary runtime permissions (READ_CONTACTS, READ_EXTERNAL_STORAGE) before loading","If the content provider does not support AssetFileDescriptor, register a custom ModelLoader that uses a stream-based fetcher instead"],"exampleFix":"// before\nGlide.with(context).load(contactUri).into(imageView);\n// after — guard with existence check + error handling\nGlide.with(context)\n  .load(contactUri)\n  .error(R.drawable.ic_person)\n  .listener(new RequestListener<Drawable>() {\n    @Override public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> t, boolean isFirst) {\n      Log.w(TAG, \"Asset unavailable for \" + model, e);\n      return false;\n    }\n    @Override public boolean onResourceReady(Drawable r, Object m, Target<Drawable> t, DataSource d, boolean i) { return false; }\n  })\n  .into(imageView);","handlingStrategy":"try-catch","validationCode":"// Verify the Uri resolves before loading\nprivate boolean isUriValid(ContentResolver cr, Uri uri) {\n  try (Cursor c = cr.query(uri, null, null, null, null)) {\n    return c != null && c.moveToFirst();\n  }\n}\n// Only load if valid:\nif (isUriValid(getContentResolver(), uri)) {\n  Glide.with(context).load(uri).into(imageView);\n}","typeGuard":null,"tryCatchPattern":"Glide.with(context)\n  .load(uri)\n  .error(R.drawable.placeholder)\n  .listener(new RequestListener<Drawable>() {\n    @Override public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {\n      // FileNotFoundException from AssetFileDescriptorLocalUriFetcher surfaces here\n      Log.w(TAG, \"Failed to load: \" + model, e);\n      return false; // let .error() placeholder show\n    }\n    @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {\n      return false;\n    }\n  })\n  .into(imageView);","preventionTips":["Verify content Uris resolve before passing them to Glide","Ensure runtime permissions (READ_CONTACTS, READ_EXTERNAL_STORAGE) are granted","Always provide .error() and .fallback() drawables for local Uri loads","Do not persist content Uris across sessions without re-validating"],"tags":["glide","uri","content-resolver","file-not-found"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}