dbt-labs/dbt-core · warning

Invalid constraint for column

Error message

Invalid constraint for column {{ column_name }}. Only `not_null` is supported.

What it means

This warning is emitted by the Spark adapter's `spark__alter_column_set_constraints` macro when applying column-level constraints. Spark SQL only supports setting `not null` via `ALTER TABLE ... CHANGE COLUMN ... SET NOT NULL`; any other constraint type (unique, primary key, check, etc.) is skipped and a warning is raised. The model still runs, but the unsupported constraint is silently not enforced.

Solutions

  1. Remove non-`not_null` constraints from the column definition in schema.yml or the model config for Spark models
  2. Keep only `not_null` constraints, which the macro translates to `ALTER TABLE ... SET NOT NULL`
  3. Enforce other constraints at the warehouse/engine level manually (e.g. via post-hook DDL) if the Spark distribution supports them
  4. Wrap constraints in a `contract` with enforced=false so dbt documents them without attempting DDL

Example fix

// before (schema.yml)
columns:
  - name: id
    constraints:
      - type: not_null
      - type: unique
// after
columns:
  - name: id
    constraints:
      - type: not_null
Defensive patterns

Strategy: validation

Validate before calling

// before running, lint schema.yml constraints for Spark targets
function hasUnsupportedConstraints(constraints) {
  return (constraints || []).filter(c => c.type !== 'not_null');
}
const unsupported = hasUnsupportedConstraints(column.constraints);
if (unsupported.length) console.warn('Spark only supports not_null; remove:', unsupported.map(c => c.type));

Prevention

When it happens

Trigger: Defining model-level/column-level `constraints` in a dbt-spark model config with any `type` other than `not_null`, then running the model so the alter-constraints step executes.

Common situations: Porting models from Postgres/BigQuery where unique or primary key constraints are declared in schema.yml; teams assuming dbt contract constraints are enforced on Spark.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at crates/dbt-loader/src/dbt_macro_assets/dbt-spark/macros/adapters.sql:231

    {% if constraint.type == 'check' and not is_incremental() %}
      {%- set constraint_hash = local_md5(column_name ~ ";" ~ constraint.expression ~ ";" ~ loop.index) -%}
      {% call statement() %}
        alter table {{ relation }} add constraint {{ constraint.name if constraint.name else constraint_hash }} check ({{ constraint.expression }});
      {% endcall %}
    {% endif %}
  {% endfor %}
{% endmacro %}

{% macro alter_column_set_constraints(relation, column_dict) %}
  {{ return(adapter.dispatch('alter_column_set_constraints', 'dbt')(relation, column_dict)) }}
{% endmacro %}

{% macro spark__alter_column_set_constraints(relation, column_dict) %}
  {% for column_name in column_dict %}
    {% set constraints = column_dict[column_name]['constraints'] %}
    {% for constraint in constraints %}
      {% if constraint.type != 'not_null' %}
        {{ exceptions.warn('Invalid constraint for column ' ~ column_name ~ '. Only `not_null` is supported.') }}
      {% else %}
        {% set quoted_name = adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name %}
        {% call statement() %}
          alter table {{ relation }} change column {{ quoted_name }} set not null {{ constraint.expression or "" }};
        {% endcall %}
      {% endif %}
    {% endfor %}
  {% endfor %}
{% endmacro %}

{% macro get_column_comment_sql(column_name, column_dict) -%}
  {% if column_name in column_dict and column_dict[column_name]["description"] -%}
    {% set escaped_description = column_dict[column_name]["description"] | replace("'", "\\'") %}
    {% set column_comment_clause = "comment '" ~ escaped_description ~ "'" %}
  {%- endif -%}
  {{ adapter.quote(column_name) }} {{ column_comment_clause }}
{% endmacro %}

View on GitHub (pinned to 0267ce9170)