MuntashirAkon/AppManager · error · FileNotFoundException

Uri inaccessible or empty.

Error message

Uri inaccessible or empty.

What it means

FileNotFoundException thrown by FileUtils.getFdFromUri when ContentResolver.openFileDescriptor returns null for the given Uri and mode. A null descriptor means the content provider could not supply a readable/writable file for the request — the Uri is inaccessible (no provider, revoked grant, missing file) or resolves to empty content.

Solutions

  1. Verify and re-acquire access: re-run the SAF picker (ACTION_OPEN_DOCUMENT) and takePersistableUriPermission for long-lived access
  2. Check ContentResolver.acquireContentProviderClient(uri) / query metadata before opening to confirm the Uri is still valid
  3. Ensure the requested mode ("r", "w") matches what the grant allows
  4. Catch FileNotFoundException around getFdFromUri and prompt the user to re-select the file

Example fix

// before
ParcelFileDescriptor fd = FileUtils.getFdFromUri(context, uri, "r");
// after
ParcelFileDescriptor fd;
try {
    fd = FileUtils.getFdFromUri(context, uri, "r");
} catch (FileNotFoundException e) {
    Toast.makeText(context, R.string.uri_no_longer_accessible, Toast.LENGTH_LONG).show();
    launchDocumentPicker(); // re-acquire the Uri
    return;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check the Uri still resolves before opening
try (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) {
    if (c == null || !c.moveToFirst()) {
        // Uri no longer accessible; re-acquire via SAF picker
    }
}

Type guard

boolean isUriOpenable(Context ctx, Uri uri) {
    try (ParcelFileDescriptor pfd = ctx.getContentResolver().openFileDescriptor(uri, "r")) {
        return pfd != null;
    } catch (FileNotFoundException | SecurityException e) {
        return false;
    }
}

Try / catch

try {
    pfd = FileUtils.getFdFromUri(context, uri, "r");
} catch (FileNotFoundException e) {
    promptUserToReSelectFile();
}

Prevention

When it happens

Trigger: Calling getFdFromUri with a content:// Uri whose provider is unavailable, whose granted permission (FLAG_GRANT_READ_URI_PERMISSION) was revoked or never granted, or with a mode the provider cannot honor; openFileDescriptor returns null instead of throwing and the helper converts it to FileNotFoundException.

Common situations: Persisted Uri permissions lost after app reinstall/reboot without takePersistableUriPermission; SAF Uri pointing to a deleted document; sharing a Uri from another app that no longer exports its provider.

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 MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/cccfb2bbb77c0767. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/utils/FileUtils.java:71

            byte[] headerBytes = new byte[4];
            is.read(headerBytes);
            header = new BigInteger(headerBytes).intValue();
        }
        return header == 0x504B0304 || header == 0x504B0506 || header == 0x504B0708;
    }

    @AnyThread
    @NonNull
    public static String getFilenameFromZipEntry(@NonNull ZipEntry zipEntry) {
        return Paths.getLastPathSegment(zipEntry.getName());
    }

    @NonNull
    public static ParcelFileDescriptor getFdFromUri(@NonNull Context context, @NonNull Uri uri, String mode)
            throws FileNotFoundException {
        ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(uri, mode);
        if (fd == null) {
            throw new FileNotFoundException("Uri inaccessible or empty.");
        }
        return fd;
    }

    @AnyThread
    @NonNull
    public static File getFileFromFd(@NonNull ParcelFileDescriptor fd) {
        return new File("/proc/self/fd/" + fd.getFd());
    }

    @AnyThread
    public static void deleteSilently(@Nullable Path path) {
        if (path == null || !path.exists()) return;
        if (!path.delete()) {
            Log.w(TAG, "Unable to delete %s", path);
        }
    }

View on GitHub (pinned to 0152f468fc)