Skip to content
Latchkey

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.

cargo output
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 variable

Common 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.

.github/workflows/ci.yml
- 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
// 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.rs that emits build metadata via cargo:rustc-env.
  • Use option_env! for variables that may legitimately be absent.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →