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
- 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.
- 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).
- Pass the value via an override lookup (`overrides_fn`) if you are embedding/running dbt programmatically and control env resolution.
- 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
- Never reference DBT_ENV_SECRET_* variables directly in Jinja; use the secret pipeline
- Reserve the DBT_ENV_SECRET prefix exclusively for secret values
- Lint models/schemas for env_var calls with the secret prefix
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
- Environment variables (starting with {DBT_INTERNAL_ENV_VAR_P
- 'env_var': environment variable '{var}' not found
- describe_dynamic_table is not supported by the {} adapter
- describe_interactive_table is not supported by the {} adapte
- The 'statement' result named '{name}' has already been loade
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/e1593265f999a87c.
Report an issue: GitHub.