jackc/pgx · error
domain base type OID not registered
Error message
domain base type OID not registered
What it means
Returned by Conn.LoadType for a typtype='d' (domain) type when its base type OID (pg_type.typbasetype) is not found in the connection's TypeMap (conn.go:1331-1333). A domain is just a named constraint over a base type, so pgx reuses the base type's Codec; without the base registered it cannot construct the domain codec.
Source
Thrown at conn.go:1333
}
dt, ok := c.TypeMap().TypeForOID(elementOID)
if !ok {
return nil, errors.New("array element OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.ArrayCodec{ElementType: dt}}, nil
case "c": // composite
fields, err := c.getCompositeFields(ctx, oid)
if err != nil {
return nil, err
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.CompositeCodec{Fields: fields}}, nil
case "d": // domain
dt, ok := c.TypeMap().TypeForOID(typbasetype)
if !ok {
return nil, errors.New("domain base type OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: dt.Codec}, nil
case "e": // enum
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.EnumCodec{}}, nil
case "r": // range
elementOID, err := c.getRangeElementOID(ctx, oid)
if err != nil {
return nil, err
}
dt, ok := c.TypeMap().TypeForOID(elementOID)
if !ok {
return nil, errors.New("range element OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.RangeCodec{ElementType: dt}}, nil
case "m": // multirangeView on GitHub (pinned to ec1a0befd2)
Solutions
- LoadType the base type first and register it, then LoadType the domain.
- Walk pg_type.typbasetype chains in dependency order before loading domains.
- If the base is built-in, ensure your TypeMap has the default codecs loaded (it does by default).
- Register the base codec manually via RegisterType if you provide a custom implementation.
Example fix
// before
dt, err := conn.LoadType(ctx, "pos_int") // domain over custom base 'my_int'
// -> "domain base type OID not registered"
// after
base, err := conn.LoadType(ctx, "my_int")
if err != nil { return err }
conn.TypeMap().RegisterType(base)
dt, err := conn.LoadType(ctx, "pos_int") Defensive patterns
Strategy: validation
Validate before calling
// resolve typbasetype and ensure it is registered first
var baseOID uint32
conn.QueryRow(ctx, "select typbasetype from pg_type where typname=$1", domainName).Scan(&baseOID)
if _, ok := conn.TypeMap().TypeForOID(baseOID); !ok {
// LoadType the base, register, then LoadType the domain
} Type guard
func baseRegistered(m *pgtype.Map, baseOID uint32) bool { _, ok := m.TypeForOID(baseOID); return ok } Try / catch
if t, err := conn.LoadType(ctx, domainName); err != nil {
if strings.Contains(err.Error(), "domain base type OID not registered") {
// load+register base, retry
}
return nil, err
} Prevention
- LoadType base types before domains.
- Walk typbasetype chains to discover and register transitively.
- Keep custom base codecs registered before loading derived domains.
When it happens
Trigger: Calling Conn.LoadType on a domain whose underlying base type is custom and unregistered — e.g. CREATE DOMAIN positive_int AS my_int where my_int is a custom type that has not been loaded yet.
Common situations: Loading a domain defined over a custom base type without first registering the base; schema changes that introduce a domain over a new base type; migrations that create domains before their base types are mapped.
Related errors
- array element OID not registered
- range element OID not registered
- multirange element OID not registered
- unknown typtype
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/867f3d854071a371.json.
Report an issue: GitHub.