## TL;DR

Environment variables in profiles.yml only resolve when wrapped in Jinja, like `user: "{{ env_var('DBT_USER') }}"`. A bare variable name is treated as a literal string, and an unset variable silently becomes empty. Export the variables in the shell that runs dbt, then confirm with `dbt debug`.

## Error

```text
"dbt environment variables" not resolving in profiles.yml
```

## Steps

1. Open `~/.dbt/profiles.yml` and check that every credential uses the env_var function, for example `user: "{{ env_var('DBT_USER') }}"`. Expected: no bare variable names anywhere in the file.
2. In the same shell that will run dbt, check the variable is actually set: `printenv DBT_USER`. Expected: it prints the value. Empty output means it was never exported.
3. Export any missing variables, then re-run `dbt debug`. Expected: the debug output ends with connection OK instead of an auth failure.
4. For optional variables, give env_var a fallback so dbt runs when they are unset: `{{ env_var('DBT_THREADS', '4') }}`. Expected: dbt no longer errors when the variable is missing.
5. Run `dbt debug --target dev` one final time. Expected: every check passes, including the connection check.

## When to use

- profiles.yml references environment variables and dbt connects with wrong or empty credentials.
- The same project works for a teammate but not for you (their shell exports the vars, yours does not).
- CI fails on connection while local runs pass.

## When not to use

- You run on dbt Cloud (set variables under Environment Settings, not in profiles.yml).
- Credentials are hardcoded and wrong (fix the values, not the variable mechanism).
- The error is a warehouse permission error after a successful connection.

## Tool compatibility

- dbt Core 1.0 and later, all adapters (Snowflake, BigQuery, Postgres, Databricks, Redshift).
- The `env_var` Jinja function is available in profiles.yml, dbt_project.yml, and model config blocks.

## Variant phrasings

### Required env var not set

dbt raises this when `env_var('NAME')` has no default and the variable is unset. Export it or add a default.

### profiles.yml credential resolves to an empty string

The variable name is misspelled or was exported in a different shell session. Check spelling with `printenv`.

## Why it happens

profiles.yml is rendered as a Jinja template before dbt parses it as YAML. Only `{{ env_var('...') }}` triggers a lookup; anything else is a literal string, so the warehouse receives the variable name (or nothing) as the credential.

## Edge cases

- Shell `.env` files are not loaded automatically; use direnv, or source the file in the same shell before running dbt.
- On Windows, set variables with `setx` in a new terminal, or the process will not see them.
- dbt Cloud ignores profiles.yml entirely, so env_var there resolves against the environment settings in the UI.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_cKXQWcC76PHz0uHCL7GaeA
