rust-lang/rust · error · anyhow::Error
opt failed optimize bitcode: {}
Error message
opt failed optimize bitcode: {} What it means
Bailed by Session::optimize when the opt subprocess exits non-zero. opt runs the passes default<O>,internalize,globaldCE over the linked bitcode; failure indicates an invalid pass pipeline, an opt version that doesn't support the requested passes, or malformed input bitcode.
Source
Thrown at src/tools/llvm-bitcode-linker/src/linker.rs:122
.arg(format!("--internalize-public-api-file={}", self.sym_path.display()))
.arg(format!("--passes={}", passes));
if !debug {
opt_cmd.arg("--strip-debug");
}
let opt_output = opt_cmd.output().context(
"An error occurred when calling opt. Make sure the llvm-tools component is installed.",
)?;
if !opt_output.status.success() {
tracing::error!(
"opt returned with Exit status: {}\n stdout: {}\n stderr: {}",
opt_output.status,
String::from_utf8(opt_output.stdout).unwrap(),
String::from_utf8(opt_output.stderr).unwrap(),
);
anyhow::bail!("opt failed optimize bitcode: {}", self.link_path.display());
};
Ok(())
}
/// Compile the optimized bitcode file to native format using `llc`
///
/// Before this can be called `optimize` needs to be called
fn compile(&mut self) -> anyhow::Result<()> {
let mut lcc_command = std::process::Command::new("llc");
if let Some(mcpu) = &self.cpu {
lcc_command.arg("--mcpu").arg(mcpu);
}
if let Some(mattr) = &self.feature {
lcc_command.arg(&format!("--mattr={}", mattr));
}View on GitHub (pinned to 7088e4b63a)
Solutions
- Inspect the logged opt stderr for the exact pass/error.
- Ensure the opt on PATH is the same LLVM version as rustc's bundled LLVM (rustup component llvm-tools).
- Check that sym_path was written and contains one symbol per line.
- Re-run with a lower Optimization level to isolate pass-specific failures.
Example fix
// before
anyhow::bail!("opt failed optimize bitcode: {}", self.link_path.display());
// after: include opt's stderr so callers can act without reading logs
let stderr = String::from_utf8_lossy(&opt_output.stderr);
anyhow::bail!(
"opt failed to optimize bitcode {} (passes={passes}): {}",
self.link_path.display(),
stderr.trim()
); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the opt binary matches rustc's LLVM and supports the passes:
fn opt_supports_passes(opt: &str, passes: &str) -> bool {
let out = std::process::Command::new(opt).arg("--help-passes").output();
matches!(out, Ok(o) if String::from_utf8_lossy(&o.stdout).contains(passes)))
} Type guard
null
Try / catch
match session.lto(opt, debug) {
Ok(()) => Ok(()),
Err(e) if e.to_string().contains("opt failed") => {
eprintln!("opt rejected the pass pipeline; check LLVM version alignment");
Err(e)
}
Err(e) => Err(e),
} Prevention
- Use the opt from rustup's llvm-tools, not a system LLVM.
- Pin the LLVM major version across the toolchain.
- Write the symbol file before invoking opt and assert it is non-empty when symbols are expected.
When it happens
Trigger: Reached after a successful link(), when opt fails. Common when the opt binary is from a different LLVM than the one that produced the bitcode, or when the Optimization level is parsed into a value opt's default<> pipeline doesn't accept.
Common situations: PATH points at a system LLVM while rustc uses its bundled LLVM; an LLVM major-version bump renamed or removed a pass; the symbol file passed via --internalize-public-api-file is empty/malformed.
Related errors
- llvm-link failed to link files {:?}
- llc failed to compile {} into {}
- llvm-readelf failed for binary {binary} with output {stdout}
- Build ID not found for binary {binary}
- unexpected base kind for gap region: {kind:?}
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/435e6c7bcab30a37.
Report an issue: GitHub.