koral--/android-gif-drawable · error · IOException

Could not open AssetFileDescriptor for

Error message

Could not open AssetFileDescriptor for <uri>

What it means

GifInfoHandle.openUri resolves a Uri via ContentResolver.openAssetFileDescriptor(uri, "r"). When the resolver returns null (the provider could not open the Uri), an IOException('Could not open AssetFileDescriptor for <uri>') is thrown, embedding the failing Uri in the message.

Solutions

  1. Verify the Uri is resolvable: check resolver.openAssetFileDescriptor(uri, "r") != null or query the provider before loading.
  2. Request and grant the necessary URI permissions (FLAG_GRANT_READ_URI_PERMISSION) for content:// URIs.
  3. Re-fetch the Uri if it came from a picker — the underlying resource may have been deleted.
  4. Wrap the load in try-catch for IOException and fall back to another source.

Example fix

// before
gifDrawable = new GifDrawableBuilder().from(resolver, staleUri).build();
// after
if (resolver.getType(staleUri) != null) {
    gifDrawable = new GifDrawableBuilder().from(resolver, staleUri).build();
} else {
    // re-pick or use fallback source
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (resolver.getType(uri) != null) { gifDrawable = new GifDrawableBuilder().from(resolver, uri).build(); }

Try / catch

try { gifDrawable = new GifDrawableBuilder().from(resolver, uri).build(); } catch (IOException e) { /* Uri unresolvable — re-pick resource or use fallback */ }

Prevention

When it happens

Trigger: Calling GifDrawableBuilder.from(resolver, uri) or GifInfoHandle.openUri with a Uri whose content provider returns null, e.g. a content:// Uri for a nonexistent/unavailable resource (non-file scheme).

Common situations: Stale content:// URIs (e.g. from a removed gallery entry); provider not exported or permission missing; Uri typo or wrong authority after app reinstall.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of koral--/android-gif-drawable@26ff795f78 (2026-09-10). Data as JSON: /api/errors/d180ace5d51d5868. Report an issue: GitHub.

Appendix: source

Thrown at android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifInfoHandle.java:104

	private static int getNativeFileDescriptor(FileDescriptor fileDescriptor, boolean closeOriginalDescriptor) throws GifIOException, ErrnoException {
		try {
			final int nativeFileDescriptor = createTempNativeFileDescriptor();
			Os.dup2(fileDescriptor, nativeFileDescriptor);
			return nativeFileDescriptor;
		} finally {
			if (closeOriginalDescriptor) {
				Os.close(fileDescriptor);
			}
		}
	}

	static GifInfoHandle openUri(ContentResolver resolver, Uri uri) throws IOException {
		if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { //workaround for #128
			return new GifInfoHandle(uri.getPath());
		}
		final AssetFileDescriptor assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r");
		if (assetFileDescriptor == null) {
			throw new IOException("Could not open AssetFileDescriptor for " + uri);
		}
		return new GifInfoHandle(assetFileDescriptor);
	}

	static native long openNativeFileDescriptor(int fd, long offset) throws GifIOException;

	static native int extractNativeFileDescriptor(FileDescriptor fileDescriptor, boolean closeOriginalDescriptor) throws GifIOException;

	static native int createTempNativeFileDescriptor() throws GifIOException;

	static native long openByteArray(byte[] bytes) throws GifIOException;

	static native long openDirectByteBuffer(ByteBuffer buffer) throws GifIOException;

	static native long openStream(InputStream stream) throws GifIOException;

	static native long openFile(String filePath) throws GifIOException;

View on GitHub (pinned to 26ff795f78)