dbt-labs/dbt-core · warning

Invalid foreign key column: {{ column_name }}

Error message

Invalid foreign key column: {{ column_name }}

What it means

During foreign key constraint DDL generation for Databricks, each column listed in the constraint's `columns` (or single `column_name`) is looked up in the model's `columns` dict. If a referenced column name does not exist on the model, dbt emits this warning and skips that column instead of rendering it into the `foreign key` clause. It exists because referencing a non-existent column would produce invalid DDL at the warehouse.

Source

Thrown at crates/dbt-loader/src/dbt_macro_assets/dbt-databricks/macros/relations/constraints.sql:250

        {% if local_md5 %}
          {{ exceptions.warn("Constraint of type " ~ type ~ " with no `name` provided. Generating hash instead for relation " ~ relation.identifier) }}
          {%- set name = local_md5("foreign_key;" ~ relation.identifier ~ ";" ~ constraint.get('expression') ~ ";") -%}
        {% else %}
          {{ exceptions.raise_compiler_error("Constraint of type " ~ type ~ " with no `name` provided, and no md5 utility.") }}
        {% endif %}    
      {% endif %}

      {% set stmt = "alter table " ~ relation.render() ~ " add constraint " ~ name ~ " foreign key" ~ constraint.get('expression') %}
    {% else %}
      {% set column_names = constraint.get('columns', []) %}
      {% if column and not column_names %}
        {% set column_names = [column['name']] %}
      {% endif %}
      {% set quoted_names = [] %}
      {% for column_name in column_names %}
        {% set column = model.get('columns', {}).get(column_name) %}
        {% if not column %}
          {{ exceptions.warn('Invalid foreign key column: ' ~ column_name) }}
        {% else %}
          {% set quoted_name = adapter.quote(column['name']) %}
          {% do quoted_names.append(quoted_name) %}
        {% endif %}
      {% endfor %}

      {% set joined_names = quoted_names|join(", ") %}

      {% set parent = constraint.get('to') %}
      {% if not parent %}
        {{ exceptions.raise_compiler_error('No parent table defined for foreign key: ' ~ expression) }}
      {% endif %}
      {% if not "." in parent %}
        {% set parent_relation = api.Relation.create(database=relation.database, schema=relation.schema, identifier=parent, type='table') %}
        {% set parent = parent_relation.render() %}
      {% endif %}

      {% if not name %}

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Open the model's YAML and add the missing column under `columns:` with a matching name
  2. Fix the typo/casing in the foreign key constraint's `columns` (or column-level `name`) so it exactly matches a declared column
  3. Remove the stale column entry from the constraint if it is no longer part of the key
  4. Re-run dbt and confirm the warning no longer appears and the FK DDL includes all intended columns

Example fix

# before
columns:
  - name: order_id
column_types: ...
constraints:
  - type: foreign_key
    columns: [order_idd, customer_id]
# after
columns:
  - name: order_id
  - name: customer_id
constraints:
  - type: foreign_key
    columns: [order_id, customer_id]
Defensive patterns

Strategy: validation

Validate before calling

# in a schema.yml hook or pre-flight script: ensure every FK column is declared
import yaml
def check_fk_columns(schema):
    for model in schema.get('models', []):
        cols = {c['name'] for c in model.get('columns', [])}
        for con in model.get('constraints', []):
            if con['type'] == 'foreign_key':
                missing = set(con.get('columns', [])) - cols
                assert not missing, f"{model['name']}: FK columns missing from columns: {missing}"

Prevention

When it happens

Trigger: A model defines a `foreign_key` constraint (model-level, with `columns: [...]`, or column-level) whose column name does not match any key in the model's `columns:` YAML block, e.g. a typo or a column added to the constraint but never declared under `columns:`.

Common situations: Renaming a column in the model without updating the foreign key constraint's column list; hand-writing constraint YAML with wrong casing (column lookup is case-sensitive as written); declaring the FK at model level while forgetting to list the referenced column under `columns:`.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — 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/1ffbf0dcf4163383. Report an issue: GitHub.