rust-lang/rust · critical · Exception

Build ID not found for binary {binary}

Error message

Build ID not found for binary {binary}

What it means

Raised by TestEnvironment.build_id() after llvm-readelf succeeded and returned JSON, but none of the NoteSections entries had Name == '.note.gnu.build-id'. The build-id is mandatory because it becomes part of the Fuchsia package name and the .build-id directory layout used by the debugger. Its absence means the binary was linked without a build-id note.

Source

Thrown at src/ci/docker/scripts/fuchsia-test-runner.py:228

            e.add_note(
                f'Failed to read "NoteSections" from llvm-readelf for binary {binary}'
            )
            e.add_note(f"elf_output: {elf_output}")
            raise

        for entry in note_sections:
            try:
                note_section = entry["NoteSection"]
                if note_section["Name"] == ".note.gnu.build-id":
                    return note_section["Notes"][0]["Build ID"]
            except Exception as e:
                e.add_note(
                    f'Failed to read ".note.gnu.build-id" from NoteSections \
                        entry in llvm-readelf for binary {binary}'
                )
                e.add_note(f"NoteSections: {note_sections}")
                raise
        raise Exception(f"Build ID not found for binary {binary}")

    def generate_buildid_dir(
        self,
        binary: Path,
        build_id_dir: Path,
        build_id: str,
        log_handler: logging.Logger,
    ):
        os.makedirs(build_id_dir, exist_ok=True)
        suffix = ".debug"
        # Hardlink the original binary
        build_id_prefix_dir = build_id_dir.joinpath(build_id[:2])
        unstripped_binary = build_id_prefix_dir.joinpath(build_id[2:] + suffix)
        build_id_prefix_dir.mkdir(parents=True, exist_ok=True)
        atomic_link(unstripped_binary, binary)
        assert unstripped_binary.exists()
        stripped_binary = unstripped_binary.with_suffix("")
        llvm_objcopy = Path(self.toolchain_dir).joinpath("bin", "llvm-objcopy")

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Inspect the binary's notes: `llvm-readelf -n <binary>` and confirm a `.note.gnu.build-id` section is listed.
  2. If missing, ensure the linker is invoked with build-id enabled (default for most targets); check RUSTFLAGS / target spec for `-Wl,--build-id=none` and remove it.
  3. Rebuild the affected crate so the note is embedded, then re-run the test runner.
  4. If the note exists but under a different JSON key, align the llvm-readelf version with what the runner expects.

Example fix

// before
# linker invoked with build-id disabled
RUSTFLAGS="-C link-arg=-Wl,--build-id=none"

// after
RUSTFLAGS=""  # let the linker emit a default build-id
# verify:
$ llvm-readelf -n <binary> | grep build-id
Defensive patterns

Strategy: validation

Validate before calling

import subprocess

def has_build_id(readelf, binary):
    out = subprocess.run([str(readelf), "-n", str(binary)],
                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
    return b"build" in out.lower() and b".note.gnu.build-id" in out

if not has_build_id(Path(env.toolchain_dir)/"bin"/"llvm-readelf", bin_path):
    raise SystemExit("binary has no .note.gnu.build-id; rebuild without --build-id=none")

Type guard

null

Try / catch

try:
    build_id = test_env.build_id(bin_path)
except Exception as e:
    if "Build ID not found" in str(e):
        logging.error("linker did not emit build-id; check RUSTFLAGS / target spec")
    raise

Prevention

When it happens

Trigger: TestEnvironment.build_id(binary) is called (via 'run' at fuchsia-test-runner.py:696) and the loop at lines 216-227 completes without returning because every entry's NoteSection.Name is something other than .note.gnu.build-id, or the Notes array is empty.

Common situations: The Rust target spec or linker flags for Fuchsia dropped -Wl,--build-id; a custom RUSTFLAGS override stripped build-id generation; the binary is a stub/wrapper rather than the real test executable; llvm-readelf JSON schema changed and the note is present under a different key.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/feb77e71c8fb18d3. Report an issue: GitHub.