Hmbown/CodeWhale · error
Android loaded-image authorities disagree: dladdr resolved…
Error message
Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {} What it means
The Android self-update proof cross-checks two independent authorities for the location of the running executable: dladdr (the dynamic linker's answer for the object containing the marker function) and the /proc/self/maps row covering the same address. After canonicalizing both paths, if they differ the updater cannot prove which file it is actually running from and refuses to proceed, since replacing the wrong file could corrupt an unrelated binary.
Solutions
- Check whether the binary path involves symlinks or bind mounts; run the update from the canonical, real path of the executable.
- Re-run the updater after re-installing the binary so dladdr and /proc/self/maps refer to the same inode; do not replace the binary underneath a running process.
- Verify the filesystem supports canonicalization consistently (avoid overlayfs quirks or FUSE mounts that report different paths).
- If it persists, capture the two reported paths from the error message and file a bug with that output.
Example fix
// before: running updater through a symlink $PREFIX/bin/codewhale update # $PREFIX/bin/codewhale -> /data/.../bin/codewhale.real // after: run the real path directly /data/app/.../bin/codewhale.real update
Defensive patterns
Strategy: validation
Validate before calling
let via_dladdr = std::fs::canonicalize(dladdr_path)?;
let via_maps = std::fs::canonicalize(maps_path)?;
if via_dladdr != via_maps {
eprintln!("authority mismatch: {via_dladdr:?} vs {via_maps:?}; refusing self-update");
return Err(anyhow!("loaded-image authorities disagree"));
} Try / catch
match run_update() {
Err(e) if e.to_string().contains("authorities disagree") => {
// fall back to manual install instructions
}
other => other?,
} Prevention
- Avoid launching the updater through symlinks or bind mounts.
- Update only from the canonical real path of the binary.
- Do not replace the binary while a process is running from it.
- Test self-update on your actual Android filesystem (overlayfs, FUSE) before relying on it.
When it happens
Trigger: android_loaded_executable_proof (during self-update) when canonicalize() of the dladdr-reported path and the maps-reported path yield different absolute paths for the same marker address.
Common situations: Symlink or bind-mount setups where one authority reports the symlink path and the other the real path outside the resolver's view; running from an overlay/twerged filesystem where canonicalization diverges; a stale maps row after the binary was replaced mid-run.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Android reported deleted loaded image
- Android dladdr could not locate the updater's loaded image
- Android dladdr returned an empty loaded-image path
- multiple /proc/self/maps rows contain the updater marker
- Android identifies runtime linker ` `; refusing to use the…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/3b95d3a2d9024b79.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/update.rs:449
) -> Result<AndroidExecutableProof> {
let mapping = parse_android_image_mapping(maps, marker)?;
validate_android_reported_path("dladdr", dladdr_path)?;
validate_android_reported_path("/proc/self/maps", &mapping.path)?;
let resolved_dladdr = dladdr_path.canonicalize().with_context(|| {
format!(
"failed to canonicalize Android dladdr path {}",
dladdr_path.display()
)
})?;
let resolved_mapping = mapping.path.canonicalize().with_context(|| {
format!(
"failed to canonicalize Android loaded-image mapping {}",
mapping.path.display()
)
})?;
if resolved_dladdr != resolved_mapping {
bail!(
"Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}",
resolved_dladdr.display(),
resolved_mapping.display()
);
}
if is_android_linker_name(&resolved_mapping) {
bail!(
"Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target",
resolved_mapping.display()
);
}
if !is_executable_file(&resolved_mapping) {
bail!(
"Android loaded image `{}` is not an executable regular file; refusing to select an update target",
resolved_mapping.display()
);
}
View on GitHub (pinned to 73e0f67d83)