pola-rs/polars · error · NotImplementedError

unsupported null type: {null_type!r}

Error message

unsupported null type: {null_type!r}

What it means

Polars handles exactly four null representations from the interchange protocol: USE_BITMASK (with USE_BYTEMASK as a variant), USE_NAN, and USE_SENTINEL. Any other ColumnNullType value falls into the else branch and raises NotImplementedError. In practice this means the producer speaks a protocol revision newer than the polars version in use.

Source

Thrown at py-polars/src/polars/interchange/from_dataframe.py:295

        return data.is_not_nan()

    elif null_type == ColumnNullType.USE_SENTINEL:
        if not allow_copy:
            msg = "bitmask must be constructed"
            raise CopyNotAllowedError(msg)

        sentinel = pl.Series([null_value])
        try:
            if column_dtype.is_temporal():
                sentinel = sentinel.cast(column_dtype)
            return data != sentinel  # noqa: TRY300
        except InvalidOperationError as e:
            msg = f"invalid sentinel value for column of type {column_dtype}: {null_value!r}"
            raise TypeError(msg) from e

    else:
        msg = f"unsupported null type: {null_type!r}"
        raise NotImplementedError(msg)


def _construct_validity_buffer_from_bitmask(
    buffer: Buffer,
    null_value: int,
    length: int,
    offset: int = 0,
    *,
    allow_copy: bool,
) -> Series:
    buffer_info = (buffer.ptr, offset, length)
    s = pl.Series._from_buffer(Boolean, buffer_info, buffer)

    if null_value != 0:
        if not allow_copy:
            msg = "bitmask must be inverted"
            raise CopyNotAllowedError(msg)
        s = ~s

View on GitHub (pinned to df599052da)

Solutions

  1. Upgrade polars to a version that supports the null type
  2. Pin or configure the producer to a protocol revision polars supports
  3. Report the gap to the polars issue tracker, including producer name and version
Defensive patterns

Strategy: try-catch

Validate before calling

from polars.interchange.protocol import ColumnNullType

SUPPORTED_NULL_TYPES = {
    ColumnNullType.USE_BITMASK,
    ColumnNullType.USE_BYTEMASK,
    ColumnNullType.USE_NAN,
    ColumnNullType.USE_SENTINEL,
}

def null_types_supported(df) -> bool:
    proto = df.__dataframe__(allow_copy=False)
    return all(
        col.describe_null()[0] in SUPPORTED_NULL_TYPES
        for col in proto.get_columns()
    )

Try / catch

try:
    out = pl.from_dataframe(df)
except NotImplementedError as e:
    if 'unsupported null type' in str(e):
        raise RuntimeError(
            'producer uses a null type this polars version does not support; '
            'upgrade polars or pin the producer protocol version'
        ) from e
    raise

Prevention

When it happens

Trigger: A producer's describe_null returns a ColumnNullType enum value outside the four kinds polars implements (e.g. a future or extension enum member).

Common situations: Version skew where the producer library is newer than polars; experimental producers implementing draft spec extensions; enum values leaking across incompatible protocol versions.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/1b7b7a8895eeca28. Report an issue: GitHub.