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
- Open the model's YAML and add the missing column under `columns:` with a matching name
- Fix the typo/casing in the foreign key constraint's `columns` (or column-level `name`) so it exactly matches a declared column
- Remove the stale column entry from the constraint if it is no longer part of the key
- 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
- Always declare every column referenced by a constraint under `columns:` in the model YAML
- Generate/validate YAML with dbt-codegen and review constraint column lists
- Add a CI lint that cross-checks constraint columns against declared columns
- Treat 'Invalid foreign key column' warnings in dbt logs as CI failures
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
- unenforced constraint type: {constraint.type}
- Constraint of type {{ type }} with no `name` provided. Gener
- unenforced constraint type: {type}
- Invalid primary key column: {column_name}
- unsupported constraint type: {{ constraint.type }}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/1ffbf0dcf4163383.
Report an issue: GitHub.