micro/go-micro · error

cannot create table

Error message

cannot create table

What it means

The pgx-backed SQL store runs a CREATE TABLE statement (via initTable) when a database/table is first accessed and wraps any execution error with 'cannot create table'. It means PostgreSQL rejected the DDL needed to materialize the store table. The wrapped cause carries the actual PostgreSQL error.

Source

Thrown at store/postgres/pgx/pgx.go:96

		}
	}
	dbObj := s.databases[database]
	if _, ok := dbObj.tables[table]; !ok {
		err := s.initTable(database, table)
		if err != nil {
			return nil, Queries{}, err
		}
	}

	return dbObj.conn, dbObj.tables[table], nil
}

func (s *sqlStore) initTable(database, table string) error {
	db := s.databases[database].conn

	_, err := db.Exec(s.options.Context, fmt.Sprintf(createTable, database, table))
	if err != nil {
		return errors.Wrap(err, "cannot create table")
	}

	_, err = db.Exec(s.options.Context, fmt.Sprintf(createMDIndex, table, database, table))
	if err != nil {
		return errors.Wrap(err, "cannot create metadata index")
	}

	_, err = db.Exec(s.options.Context, fmt.Sprintf(createExpiryIndex, table, database, table))
	if err != nil {
		return errors.Wrap(err, "cannot create expiry index")
	}

	s.databases[database].tables[table] = NewQueries(database, table)

	return nil
}

func (s *sqlStore) initDB(database string) error {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Grant CREATE privileges on the database/schema to the configured DB user: GRANT CREATE ON DATABASE <db> TO <user>.
  2. Verify the configured database exists and the connection string points to it.
  3. Check the wrapped error for the exact PostgreSQL message (e.g. permission denied, syntax error).
  4. Pre-create the table manually if DDL is restricted in your environment.
  5. Confirm PostgreSQL version compatibility with the store's DDL.

Example fix

-- before
-- user lacks privileges, CREATE TABLE fails
-- after
GRANT CREATE ON DATABASE micro TO micro_user;
-- or pre-create:
-- CREATE TABLE IF NOT EXISTS micro.keys (...);
Defensive patterns

Strategy: validation

Validate before calling

// before using the store
var exists bool
err := adminConn.QueryRow(ctx, "SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname=$1)", dbName).Scan(&exists)
// and verify privileges:
// SELECT has_database_privilege(current_user, $1, 'CREATE');

Try / catch

if err := store.Init(); err != nil {
	var pgErr *pgconn.PgError
	if errors.As(err, &pgErr) && pgErr.Code == "42501" { // insufficient privilege
		return fmt.Errorf("db user lacks CREATE privilege: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: First Read/Write/List against a database+table combination that has not been initialized, when the CREATE TABLE ... IF NOT EXISTS statement fails: syntax/permission errors, invalid database or table identifier, connection failure, or unsupported PostgreSQL version.

Common situations: DB user lacks CREATE privilege on the schema/database; connected to the wrong database name configured via store options; PostgreSQL version too old for the generated DDL; read-only replicas or restricted managed databases (e.g. limited cloud roles) blocking DDL.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/b54a4d88802b0a03. Report an issue: GitHub.