MuntashirAkon/AppManager · error · IOException

+ path + is inaccessible.

Error message

+ path + is inaccessible.

What it means

VirtualFileSystem.newInputStream first performs a POSIX-style access check (checkAccess with R_OK) on the virtual path. If read access is denied — the underlying node's permission bits or its backing file disallow reading — an IOException stating '<path> is inaccessible.' is thrown before the node is even resolved.

Source

Thrown at app/src/main/java/io/github/muntashirakon/io/fs/VirtualFileSystem.java:964

        checkMounted();
        return Objects.requireNonNull(getOptions()).uidGidPair;
    }

    public void setUidGid(String path, int uid, int gid) {
        // TODO: 7/12/22 This should either throw ErrnoException or a boolean value
        checkMounted();
    }

    public boolean createLink(String link, String target, boolean soft) {
        checkMounted();
        return false;
    }

    /* I/O APIs */
    @NonNull
    public FileInputStream newInputStream(String path) throws IOException {
        if (!checkAccess(path, OsConstants.R_OK)) {
            throw new IOException(path + " is inaccessible.");
        }
        Node<?> targetNode = getNode(path);
        if (targetNode == null) {
            throw new FileNotFoundException(path + " does not exist.");
        }
        if (!targetNode.isFile()) {
            throw new IOException(path + " is not a file.");
        }
        return new FileInputStream(getCachedFile(targetNode, false));
    }

    @NonNull
    public FileOutputStream newOutputStream(String path, boolean append) throws IOException {
        if (!checkAccess(path, OsConstants.W_OK)) {
            throw new IOException(path + " is inaccessible.");
        }
        Node<?> targetNode = getNode(path);
        if (targetNode == null) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check checkAccess/readability first and skip or request elevated access for unreadable paths.
  2. Mount with options that grant read permissions (or fix the underlying node's mode via chmod when it is a real file).
  3. Verify the path is a readable file entry, not a special/write-only node.
  4. Catch IOException and present a permission-oriented message rather than a generic failure.

Example fix

// before
InputStream in = vfs.newInputStream(path);
// after
if (!vfs.checkAccess(path, OsConstants.R_OK)) {
    throw new IOException("No read access: " + path);
}
InputStream in = vfs.newInputStream(path);
Defensive patterns

Strategy: validation

Validate before calling

if (!vfs.checkAccess(path, OsConstants.R_OK)) {
    throw new IOException("No read access: " + path);
}

Try / catch

try (FileInputStream in = vfs.newInputStream(path)) {
    // read
} catch (IOException e) {
    if (String.valueOf(e.getMessage()).endsWith("is inaccessible.")) {
        // surface permission issue or request elevated access
    } else throw e;
}

Prevention

When it happens

Trigger: Opening an input stream on a path inside a mounted APK/DEX whose entry's access check returns false: file mode lacks read permission, the backing resource is unreadable in the current process context, or the path points to an entry the VFS marks non-readable.

Common situations: Reading entries from an APK mounted with restrictive options; attempting reads as a non-root process on nodes whose modes assume root; reading paths that only exist as write-only placeholders.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/81e6395430ae17f8. Report an issue: GitHub.