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
- Check the wrapped MySQL error for the precise cause
- Grant CREATE privilege: GRANT CREATE ON <db>.* TO '<user>'@'%';
- Use a valid, simple namespace/table name (alphanumeric/underscore)
- 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
- Use CREATE-privileged DB user or pre-create tables via migrations
- Restrict namespaces to alphanumeric/underscore characters
- Ensure MySQL is not in read-only mode (check super_read_only, disk space)
- Smoke-test store configure in CI against a real MySQL
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
- Couldn't use database
- Couldn't insert record ${key}
- failed to prepare read statement
- failed to prepare write statement
- failed to prepare delete statement
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/e0a56a9c1238d6de.
Report an issue: GitHub.