rust-lang/cargo · error

build script logged errors

Error message

build script logged errors

What it means

A build script (`build.rs`) finished, but Cargo's collected log messages contain at least one with `Severity::Error`. Cargo treats this as a build failure even if the process exited 0, surfacing the captured messages via `insert_log_messages_in_build_outputs` and bailing with the generic `"build script logged errors"`.

Solutions

  1. Re-run with `cargo build -vv` to see the build script's logged messages surfaced in build outputs.
  2. Fix the build script to not emit error-level output; route diagnostics to a file or use `cargo:warning` intentionally.
  3. Ensure the build script exits non-zero only on real failure and zero on success with no error logs.
  4. If using a build-dependency that misbehaves, pin or patch it.

Example fix

// before (build.rs)
eprintln!("error: something went wrong but we continue");
Ok(())

// after
eprintln!("warning: non-fatal, continuing");
Ok(())
Defensive patterns

Strategy: try-catch

Validate before calling

fn build_script_emits_no_errors(logs: &[(Severity, String)]) -> bool {
    !logs.iter().any(|(s, _)| *s == Severity::Error)
}

Type guard

null

Try / catch

match run_build_script(unit) {
    Err(e) if e.to_string() == "build script logged errors" => {
        log::error!("build script reported errors; see build output"); surface_build_outputs()
    }
    r => r,
}

Prevention

When it happens

Trigger: A build script writes to stderr in a format Cargo interprets as an error (or uses `cargo:warning`/error-level directives that escalate), or a panic-style message was logged before completion; often from `println!("cargo:...")` misuse or an explicit error emission.

Common situations: Build scripts that print to stderr expecting it to be ignored; crates whose `build.rs` emits `cargo:rustc-link-lib` after a partial failure; panics in build scripts whose messages are captured.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/034ba5c597aaa8bf. Report an issue: GitHub.

Appendix: source

Thrown at src/compiler/custom_build.rs:672

                build_script_outputs,
                id,
                metadata_hash,
                log_messages_in_case_of_panic,
            );
            return Err(error);
        }
        // ... or it logged any errors
        else if log_messages_in_case_of_panic
            .iter()
            .any(|(severity, _)| *severity == Severity::Error)
        {
            insert_log_messages_in_build_outputs(
                build_script_outputs,
                id,
                metadata_hash,
                log_messages_in_case_of_panic,
            );
            anyhow::bail!("build script logged errors");
        }

        let output = output.unwrap();

        // After the build command has finished running, we need to be sure to
        // remember all of its output so we can later discover precisely what it
        // was, even if we don't run the build command again (due to freshness).
        //
        // This is also the location where we provide feedback into the build
        // state informing what variables were discovered via our script as
        // well.
        paths::write(&run_files.stdout, &output.stdout)?;
        // This mtime shift allows Cargo to detect if a source file was
        // modified in the middle of the build.
        paths::set_file_time_no_err(run_files.stdout, timestamp);
        paths::write(&run_files.stderr, &output.stderr)?;
        paths::write(&run_files.root_output, paths::path2bytes(&script_out_dir)?)?;
        let parsed_output = BuildOutput::parse(

View on GitHub (pinned to 98a09e7e7d)