micro/go-micro · error
failed to prepare read statement
Error message
failed to prepare read statement
What it means
initDB prepares the SELECT statement used by sqlStore.Read; if db.Prepare fails, Read cannot work and configure aborts. Preparation failures usually indicate SQL syntax problems from interpolated names or a broken/dead connection to MySQL.
Source
Thrown at store/mysql/mysql.go:166
_, 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")
}
return nil
}
func (s *sqlStore) configure() error {
nodes := s.options.Nodes
if len(nodes) == 0 {View on GitHub (pinned to 24529f1404)
Solutions
- Check the wrapped cause for a MySQL error code (connection vs syntax)
- Verify database/table names form valid identifiers
- Recreate the store or call configure again to reopen the connection
- Confirm the connection DSN and MySQL server health
Defensive patterns
Strategy: retry
Validate before calling
if err := db.Ping(); err != nil {
return fmt.Errorf("mysql unreachable before store configure: %w", err)
} Try / catch
if err := st.Init(opts...); err != nil {
if strings.Contains(err.Error(), "failed to prepare") {
time.Sleep(time.Second)
return st.Init(opts...) // reconnect and re-prepare
}
return err
} Prevention
- Ping MySQL before store configuration
- Keep namespaces as valid SQL identifiers
- Avoid proxies that disable server-side prepared statements
- Retry configure on transient connection failures
When it happens
Trigger: configure() -> initDB() calls s.db.Prepare("SELECT ... WHERE `key` = ?") and the driver returns an error, typically after a connection drop or with an invalid database.table identifier.
Common situations: MySQL connection dropped between CREATE TABLE and Prepare; malformed namespace producing invalid `<db>.<table>` SQL; driver version incompatibility; server-side PREPARE restrictions.
Related errors
- failed to prepare write statement
- failed to prepare delete statement
- Couldn't insert record ${key}
- unsupported statement
- Couldn't use database
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/28310be74f43bae8.
Report an issue: GitHub.