micro/go-micro · critical

Couldn't create table

Error message

Couldn't create table

What it means

initDB runs CREATE TABLE IF NOT EXISTS for the namespace's table after selecting the database; if MySQL rejects the DDL the store cannot operate and configure fails with this message. Typical causes are privileges, a reserved/invalid table name, or the database being unavailable.

Source

Thrown at store/mysql/mysql.go:158

}

func (s *sqlStore) initDB() error {
	// Create the namespace's database
	_, err := s.db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s ;", s.database))
	if err != nil {
		return err
	}

	_, err = s.db.Exec(fmt.Sprintf("USE %s ;", s.database))
	if err != nil {
		return errors.Wrap(err, "Couldn't use database")
	}

	// Create a table for the namespace's prefix
	createSQL := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (`key` varchar(255) primary key, value blob null, expiry timestamp not null);", s.table)
	_, err = s.db.Exec(createSQL)
	if err != nil {
		return errors.Wrap(err, "Couldn't create table")
	}

	// prepare statements
	var prepareErr error

	s.readPrepare, prepareErr = s.db.Prepare(fmt.Sprintf("SELECT `key`, value, expiry FROM %s.%s WHERE `key` = ?;", s.database, s.table))
	if prepareErr != nil {
		return errors.Wrap(prepareErr, "failed to prepare read statement")
	}

	s.writePrepare, prepareErr = s.db.Prepare(fmt.Sprintf("INSERT INTO %s.%s (`key`, value, expiry) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE `value`= ?, `expiry` = ?", s.database, s.table))
	if prepareErr != nil {
		return errors.Wrap(prepareErr, "failed to prepare write statement")
	}

	s.deletePrepare, prepareErr = s.db.Prepare(fmt.Sprintf("DELETE FROM %s.%s WHERE `key` = ?;", s.database, s.table))
	if prepareErr != nil {
		return errors.Wrap(prepareErr, "failed to prepare delete statement")

View on GitHub (pinned to 24529f1404)

Solutions

  1. Check the wrapped MySQL error for the precise cause
  2. Grant CREATE privilege: GRANT CREATE ON <db>.* TO '<user>'@'%';
  3. Use a valid, simple namespace/table name (alphanumeric/underscore)
  4. Ensure MySQL is writable (not read-only, disk not full)

Example fix

// before
mysql.NewStore(store.Table("my-table 1")) // invalid identifier
// after
mysql.NewStore(store.Table("micro_store"))
Defensive patterns

Strategy: validation

Validate before calling

// validate namespace before configure
var valid = regexp.MustCompile(`^[A-Za-z0-9_]+$`)
if !valid.MatchString(namespace) {
    return fmt.Errorf("invalid table name from namespace %q", namespace)
}

Prevention

When it happens

Trigger: configure() -> initDB() executes the CREATE TABLE statement and MySQL returns an error (missing CREATE privilege, syntax/identifier issues from a bad namespace/table option, storage engine errors).

Common situations: MySQL user created without DDL rights; namespace containing illegal characters interpolated into the table name; MySQL in read-only mode; table name colliding with reserved words due to missing quoting.

Related errors


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