unicity-aos/aos-ce · error · std::io::Error
bundled executable is not executable at
Error message
bundled {label} executable is not executable at {} What it means
This io::Error (PermissionDenied) is thrown by ensure_runtime_executable in crates/unicity-aos-bootstrap/src/lib.rs when a bundled executable exists as a regular file but its Unix permission bits grant no execute access to anyone (mode & 0o111 == 0). The library checks the binary before spawning it so a confusing exec failure never happens later; here the file was found but is not runnable as-is.
Solutions
- Restore the execute bit: chmod +x <path shown in the error message> and retry.
- Re-extract or reinstall the bundled artifact in a way that preserves the executable permission (tar -xpf, correct umask).
- If packaging the binary yourself, set mode 0755 (or at least 0o111 bits) on the file in the build/install step.
- Verify with 'ls -l <path>' that at least one execute bit (u/g/o) is set before re-running.
Example fix
// before (shell): archive extraction lost the exec bit tar -xzf aos-bundle.tar.gz -C /opt/aos // after chmod +x /opt/aos/bin/runtime && tar -xzf aos-bundle.tar.gz -C /opt/aos # or chmod after extraction
Defensive patterns
Strategy: validation
Validate before calling
use std::os::unix::fs::PermissionsExt;
let md = std::fs::metadata(&binary)?;
if !md.is_file() || md.permissions().mode() & 0o111 == 0 {
return Err(format!("{} is missing the execute bit; run: chmod +x {}", binary.display(), binary.display()));
} Try / catch
match std::fs::metadata(&binary) {
Ok(md) if md.is_file() && md.permissions().mode() & 0o111 != 0 => { /* proceed */ }
_ => eprintln!("bundled runtime missing or not executable; run `chmod +x <path>` or reinstall"),
} Prevention
- Extract bundles with tools that preserve the executable bit (tar -xpf) instead of unzip where possible.
- Add a chmod +x step to install scripts and containerfiles after copying the binary.
- Verify the packaged file mode (0755) in CI before publishing artifacts.
When it happens
Trigger: Calling foreground_daemon_command or ensure_runtime_available (or run/spawn variants that call ensure_runtime_executable) when the binary at the resolved runtime path exists and is a file, but has permission bits like 0644/0600 — i.e. no x bit for user, group, or other.
Common situations: The bundled binary was extracted from an archive (tar/zip) that lost the execute bit; a package or container build copied the file without preserving permissions; a post-install chmod step was skipped; the file was written programmatically with default non-executable permissions.
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
- product manifest path must be a regular file
- temporary product manifest path must be a regular file
- bundled executable not found at
- AOS managed path must be a real directory
- AOS_HOME and HOME are both unset
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/f97f91cf905aad3f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/lib.rs:544
)
} else {
error
}
})?;
if !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!(
"bundled {label} executable not found at {}",
binary.display()
),
));
}
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
if metadata.permissions().mode() & 0o111 == 0 {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!(
"bundled {label} executable is not executable at {}",
binary.display()
),
));
}
}
Ok(())
}
}
fn create_private_dir(path: &Path) -> io::Result<()> {
fs::create_dir_all(path)?;
let metadata = fs::symlink_metadata(path)?;
if metadata.file_type().is_symlink() || !metadata.is_dir() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,View on GitHub (pinned to f6f22024fb)