psycopg/psycopg2 · error · ProgrammingError
range types not available in version %s
Error message
range types not available in version %s
What it means
Raised by RangeCaster._from_db() (lib/_range.py:351-353) when the connected PostgreSQL server reports a version below 9.2 (server_version < 90200). Range types (int4range, daterange, tsrange, etc.) were introduced in PostgreSQL 9.2, so querying pg_range on an older server is meaningless and the function refuses to proceed.
Source
Thrown at lib/_range.py:352
except TypeError:
pass
if self.range is None:
raise TypeError(
'pyrange must be a type or a Range strict subclass')
@classmethod
def _from_db(self, name, pyrange, conn_or_curs):
"""Return a `RangeCaster` instance for the type *pgrange*.
Raise `ProgrammingError` if the type is not found.
"""
from psycopg2.extensions import STATUS_IN_TRANSACTION
from psycopg2.extras import _solve_conn_curs
conn, curs = _solve_conn_curs(conn_or_curs)
if conn.info.server_version < 90200:
raise ProgrammingError("range types not available in version %s"
% conn.info.server_version)
# Store the transaction status of the connection to revert it after use
conn_status = conn.status
# Use the correct schema
if '.' in name:
schema, tname = name.split('.', 1)
else:
tname = name
schema = 'public'
# get the type oid and attributes
curs.execute("""\
select rngtypid, rngsubtype, typarray
from pg_range r
join pg_type t on t.oid = rngtypid
join pg_namespace ns on ns.oid = typnamespaceView on GitHub (pinned to 3a6d9d6ddc)
Solutions
- Upgrade the PostgreSQL server to 9.2 or newer (9.2 is itself ancient; prefer a supported major version).
- Verify the connection target with 'SELECT version();' and fix the DSN/host if it points to the wrong server.
- If upgrade is impossible, avoid the range API entirely and model the data with separate columns.
Example fix
// before
register_range('int4range', NumericRange, old_conn) # server is 9.1
// after
# point at an upgraded server (9.2+) then:
register_range('int4range', NumericRange, new_conn) Defensive patterns
Strategy: validation
Validate before calling
if conn.info.server_version < 90200:
raise RuntimeError(f'range types require PostgreSQL >= 9.2, got {conn.info.server_version}') Type guard
def server_supports_ranges(conn) -> bool:
return conn.info.server_version >= 90200 Try / catch
try:
caster = register_range(name, pyrange, conn)
except ProgrammingError as e:
if 'range types not available' in str(e):
# fall back to non-range representation
pass
else: raise Prevention
- Check SELECT version() / server_version before registering range casters.
- Gate range-dependent features behind a server-version capability check.
When it happens
Trigger: Calling register_range(pgrange, pyrange, conn_or_curs) or otherwise invoking RangeCaster._from_db() against a database whose server version is < 9.2. The check reads conn.info.server_version.
Common situations: Connecting to a legacy PostgreSQL deployment (8.x, 9.0, 9.1) still common in older on-premise or appliance environments. Also seen when a connection string accidentally points to a standby/replica running an older major version, or after a botched upgrade.
Related errors
- PostgreSQL range '{name}' not found
- bound flags not valid: {bounds!r}
- RangeAdapter must be subclassed overriding its name or the g
- pgrange must be a string or a RangeAdapter strict subclass
- pyrange must be a type or a Range strict subclass
AI-assisted analysis of psycopg/psycopg2@3a6d9d6ddc (2026-08-04).
Data as JSON: /data/errors/28f11888704d72ca.json.
Report an issue: GitHub.