Rust "environment variable not defined" from env! in CI
Code uses env!("X") to read an environment variable at compile time, but X wasn’t set in the CI environment (or wasn’t re-exported by the build script). env! is a hard compile error when the variable is absent - unlike option_env!, which is allowed to be missing.
What this error means
The build fails with environment variable X not defined at compile time, naming a variable like DATABASE_URL, GIT_HASH, or a custom build flag. It builds locally where your shell exports the variable but fails on the bare runner that doesn’t.
error: environment variable `GIT_HASH` not defined at compile time
--> src/version.rs:2:25
|
2 | const GIT_HASH: &str = env!("GIT_HASH");
| ^^^^^^^^^^^^^^^^^
= help: use `option_env!("GIT_HASH")` to handle a missing variableCommon causes
A required build-time env var isn’t set in CI
env!("X") reads the variable when the crate is compiled. If CI never exports X (e.g. it’s only in your local shell), the compile fails outright.
A build script that should emit it didn’t
A build.rs is expected to compute and cargo:rustc-env=X=... the value. If the script didn’t run or didn’t print that directive, env! sees nothing.
How to fix it
Set the variable in the CI environment
Export the required variable in the workflow before the build step.
- run: cargo build --locked
env:
GIT_HASH: ${{ github.sha }}Emit it from build.rs, or use option_env!
Have the build script provide the value, or make the variable optional so a missing one doesn’t fail the build.
// build.rs
fn main() {
let hash = std::env::var("GIT_HASH").unwrap_or_else(|_| "unknown".into());
println!("cargo:rustc-env=GIT_HASH={hash}");
}
// or in source: const GIT_HASH: Option<&str> = option_env!("GIT_HASH");How to prevent it
- Set every
env!-required variable in the CI workflow, not just locally. - Prefer a
build.rsthat emits build metadata viacargo:rustc-env. - Use
option_env!for variables that may legitimately be absent.