micro/go-micro · error
model/postgres: create index: %w
Error message
model/postgres: create index: %w
What it means
During Register, after creating the table, the postgres model creates a non-unique index for every schema field flagged Index (excluding keys) via CREATE INDEX IF NOT EXISTS. If Postgres rejects the index creation, the error is wrapped as "model/postgres: create index" with the driver error as the cause.
Source
Thrown at model/postgres/postgres.go:74
if f.IsKey {
col += " PRIMARY KEY"
}
cols = append(cols, col)
}
query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s)", quoteIdent(schema.Table), strings.Join(cols, ", "))
if _, err := d.db.Exec(query); err != nil {
return fmt.Errorf("model/postgres: create table: %w", err)
}
for _, f := range schema.Fields {
if f.Index && !f.IsKey {
idx := fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (%s)",
quoteIdent("idx_"+schema.Table+"_"+f.Column),
quoteIdent(schema.Table),
quoteIdent(f.Column))
if _, err := d.db.Exec(idx); err != nil {
return fmt.Errorf("model/postgres: create index: %w", err)
}
}
}
return nil
}
func (d *postgresModel) schema(v interface{}) (*model.Schema, error) {
t := model.ResolveType(v)
d.mu.RLock()
s, ok := d.types[t]
d.mu.RUnlock()
if !ok {
return nil, model.ErrNotRegistered
}
return s, nil
}
View on GitHub (pinned to 24529f1404)
Solutions
- Inspect the wrapped driver error to see which index/column failed.
- Shorten the table or column name so idx_<table>_<column> fits within 63 characters.
- Grant CREATE privilege on the schema/table to the connecting role.
- Drop or rename the conflicting existing index, or manage indexes via migrations instead.
Example fix
// before
Field{Name: "very_long_column_name_that_pushes_identifier_over_limit", Index: true}
// after
// rename column or disable auto index and create it manually
Field{Name: "long_col", Index: true}
-- manual: CREATE INDEX IF NOT EXISTS idx_tbl_long_col ON tbl (long_col); Defensive patterns
Strategy: try-catch
Validate before calling
// check identifier length limit (Postgres max 63 bytes) before Register
func indexNameFits(table, column string) bool {
return len("idx_"+table+"_"+column) <= 63
} Try / catch
if err := store.Register(ctx, &User{}); err != nil {
if strings.Contains(err.Error(), "create index") {
log.Printf("index creation failed (check name length/privileges): %v", err)
// optionally continue without secondary indexes
return nil
}
return err
} Prevention
- Keep table+column names short enough that idx_<table>_<column> stays under 63 characters.
- Only set Index: true on fields that genuinely need secondary indexes.
- Ensure the DB role can create indexes on the schema.
- Check for pre-existing conflicting index names before deploying schema changes.
When it happens
Trigger: Registering a schema where an indexed field's column name is invalid/reserved, the table owner lacks CREATE index privilege, the index name exceeds PostgreSQL's 63-character identifier limit, or a conflicting index of a different definition exists under the same name.
Common situations: Long table+column names producing idx_ names > 63 chars (Postgres silently truncates or errors in some toolchains), restricted production DB roles, or schema changes where an existing index conflicts.
Related errors
- model/postgres: create table: %w
- Database connection not initialized
- model/postgres: create: %w
- model/postgres: update: %w
- cannot create metadata index
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/efe4a56e6341451c.
Report an issue: GitHub.