MuntashirAkon/AppManager · error · IOException
Couldn't create symbolic link ${file} pointing to ${linkName
Error message
Couldn't create symbolic link ${file} pointing to ${linkName} What it means
While extracting a tar entry that is a symbolic link, TarUtils.extract deletes any existing file at the target location and calls ExtendedFile.createNewSymbolicLink(linkName). If the OS-level symlink creation fails (returns false), it throws IOException("Couldn't create symbolic link <file> pointing to <linkName>"). Common underlying causes are filesystems that do not support symlinks (FAT/exFAT, some external storage) or lack of permission.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/utils/TarUtils.java:188
file.delete();
continue;
}
// Check if the given entry is a link.
if (entry.isSymbolicLink() && file.getFilePath() != null) {
if ((!Paths.isUnderFilter(file, dest, filterPatterns) || Paths.willExclude(file, dest, exclusionPatterns))) {
// Do not create this link even if it is a directory
continue;
}
String linkName = entry.getLinkName();
// There's no need to check if the linkName exists as it may be extracted
// after the link has been created
// Special check for /data/app
if (linkName.startsWith("/data/app/")) {
linkName = getAbsolutePathToDataApp(linkName, realDataAppPath);
}
file.delete();
if (!file.createNewSymbolicLink(linkName)) {
throw new IOException("Couldn't create symbolic link " + file + " pointing to " + linkName);
}
continue; // links do not need permission fixes
} else {
// Zip slip vulnerability might still be present
String realFilePath = file.getRealFilePath();
if (realDestPath != null && realFilePath != null && !realFilePath.startsWith(realDestPath)) {
throw new IOException("Zip slip vulnerability detected!" +
"\nExpected dest: " + new File(realDestPath, entry.getName()) +
"\nActual path: " + realFilePath);
}
if (!entry.isDirectory()) {
try (OutputStream os = file.openOutputStream()) {
IoUtils.copy(tis, os);
}
}
}
// Fix permissions
TarArchiveEntry finalEntry = entry;View on GitHub (pinned to 0152f468fc)
Solutions
- Extract to internal app storage (context.getFilesDir()) which supports symlinks, instead of external/shared storage
- Check/create a test symlink in the destination beforehand and warn the user if unsupported
- Handle the failed createNewSymbolicLink by copying the link target's content as a regular file fallback
- Catch IOException around extract and report which file/link failed
Example fix
// before
TarUtils.extract(tarIn, destDir, ...);
// after
try {
TarUtils.extract(tarIn, destDir, ...);
} catch (IOException e) {
if (e.getMessage().startsWith("Couldn't create symbolic link")) {
Log.w(TAG, "Symlinks unsupported on " + destDir + "; extracting without links");
TarUtils.extract(tarIn, destDir, ... /* symlinkFallback=true or filter links */);
} else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
File probe = new File(destDir, ".symlink_probe");
boolean symlinksSupported = probe.createNewSymbolicLink("probe_target");
probe.delete(); Type guard
boolean supportsSymlinks(File dir) {
File p = new File(dir, ".probe" + System.nanoTime());
try { return p.createNewSymbolicLink("x") | p.delete(); } catch (IOException e) { return false; }
} Try / catch
try {
TarUtils.extract(in, dest, filters);
} catch (IOException e) {
if (e.getMessage().startsWith("Couldn't create symbolic link")) {
// fallback: re-extract with links skipped or copy link targets
} else throw e;
} Prevention
- Extract symlink-bearing archives only to internal storage that supports symlinks
- Probe symlink support in the destination before extraction
- Avoid vFAT/exFAT and FUSE-mounted shared storage for archive restore
When it happens
Trigger: Extracting an archive containing symlink entries onto a destination filesystem without symlink support (vFAT SD card, /sdcard FUSE restrictions), or in a location the app lacks write/create permission for; Android may also block symlink creation depending on the mount and target path.
Common situations: Extracting app backups or APK splits with relative symlinks to external storage; restoring archives to shared storage that silently converts or rejects symlinks; SELinux policies denying symlink creation in the destination.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Couldn't find any writable Obb dir
- Could not delete the selected backups
- Could not create package staging directory
- Could not create staging files
- Failed to access properties of the KeyStore folder.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/81e96e56a391497d.
Report an issue: GitHub.