dbt-labs/dbt-core · error · minijinja::Error (InvalidOperation)

Secret environment variables (starting with {SECRET_ENV_VAR_

Error message

Secret environment variables (starting with {SECRET_ENV_VAR_PREFIX}) cannot be accessed here

What it means

The `env_var` Jinja function refuses to read environment variables whose name starts with the reserved secret prefix `DBT_ENV_SECRET`. These variables are meant to be resolved through dbt's secret-handling pipeline (replaced with a placeholder) rather than being read directly in contexts where `placeholder_on_secret_access` is false. Reading them inline would leak secret values into compiled output or logs, so the library hard-errors instead.

Source

Thrown at crates/dbt-jinja-vars/src/env_var.rs:53

#[allow(clippy::type_complexity)]
pub fn env_var(
    placeholder_on_secret_access: bool,
    overrides_fn: Option<&LookupFn>,
    tracker: Option<&dyn Fn(&str, &str)>,
    _state: &State,
    args: &[Value],
) -> Result<Value, Error> {
    let iter = ArgsIter::new("env_var", &["var"], args);
    let var = iter.next_arg::<&str>()?;
    let default = iter.next_kwarg::<Option<&Value>>("default")?;

    if let Some(value) = overrides_fn.and_then(|f| f(var)) {
        return Ok(value);
    }

    let is_secret = var.starts_with(SECRET_ENV_VAR_PREFIX);
    if is_secret && !placeholder_on_secret_access {
        let err = Error::new(
            ErrorKind::InvalidOperation,
            format!(
                "Secret environment variables (starting with {SECRET_ENV_VAR_PREFIX}) \
                cannot be accessed here"
            ),
        );
        return Err(err);
    }
    let is_internal = var.starts_with(DBT_INTERNAL_ENV_VAR_PREFIX);
    if is_internal {
        let err = Error::new(
            ErrorKind::InvalidOperation,
            format!(
                "Environment variables (starting with {DBT_INTERNAL_ENV_VAR_PREFIX}) \
                cannot be accessed here"
            ),
        );
        return Err(err);

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Remove the `DBT_ENV_SECRET` prefix from the variable name if it is not actually a secret, or store the value under a non-reserved name.
  2. Access the secret through dbt's supported secret-resolution path (the invocation with `placeholder_on_secret_access = true`, which returns the `$$$DBT_SECRET_START$$${}$$$DBT_SECRET_END$$$` placeholder instead of erroring).
  3. Pass the value via an override lookup (`overrides_fn`) if you are embedding/running dbt programmatically and control env resolution.
  4. If you only need a fallback, use `env_var('NAME', default=...)` with a non-secret variable name.

Example fix

// before (Jinja)
{{ env_var('DBT_ENV_SECRET_API_TOKEN') }}
// after
{{ env_var('API_TOKEN') }}  <!-- value exported without the reserved DBT_ENV_SECRET prefix -->
Defensive patterns

Strategy: try-catch

Validate before calling

// Jinja pre-check
{% if var_name.startswith('DBT_ENV_SECRET') %}{{ exceptions.raise_compiler_error('use the secret pipeline for ' ~ var_name) }}{% endif %}

Try / catch

// Rust embedding dbt
match env_var(false, None, None, &state, &args) {
    Err(e) if e.to_string().contains("Secret environment variables") => {
        // route through secret-placeholder resolution (placeholder_on_secret_access = true)
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `{{ env_var('DBT_ENV_SECRET_MY_KEY') }}` (any var name starting with `DBT_ENV_SECRET`) from Jinja while the `env_var` invocation was built with `placeholder_on_secret_access = false`. Overrides via `overrides_fn` that return a value bypass the check, but a direct environment lookup of a secret-prefixed name errors immediately at env_var.rs:53.

Common situations: Users reference secret env vars (e.g. `DBT_ENV_SECRET_API_TOKEN`) directly in models, schemas.yml, or profiles-rendering Jinja in a context that does not support secret placeholders, such as certain compile modes, docs generation, or partial parsing paths where placeholder substitution is disabled.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/e1593265f999a87c. Report an issue: GitHub.