micro/go-micro · error
failed to prepare write statement
Error message
failed to prepare write statement
What it means
initDB prepares the INSERT ... ON DUPLICATE KEY UPDATE statement used by sqlStore.Write; a Prepare error means the write path is unusable and configuration fails immediately rather than failing lazily on first Write.
Source
Thrown at store/mysql/mysql.go:171
// 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 {
nodes = []string{"localhost:3306"}
}
database := s.options.Database
if len(database) == 0 {View on GitHub (pinned to 24529f1404)
Solutions
- Read the wrapped cause to distinguish connection vs syntax errors
- Ensure the namespace/table produce valid SQL identifiers
- Reconnect/retry configure; check MySQL server and proxy health
- If the proxy forbids prepared statements, switch to a store backend without them
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 write statement") {
time.Sleep(time.Second)
return st.Init(opts...)
}
return err
} Prevention
- Verify upsert SQL works on your MySQL version (ON DUPLICATE KEY UPDATE)
- Check max_prepared_stmt_count on the server
- Use valid identifier namespaces
- Add bounded retries around store Init
When it happens
Trigger: configure() -> initDB() calls s.db.Prepare with the upsert SQL and the MySQL driver/server rejects it — broken connection, invalid `<db>.<table>` identifiers, or server refusing PREPARE.
Common situations: Flaky MySQL connectivity during startup; bad namespace chars breaking the interpolated SQL; older MySQL versions or proxies (e.g. some managed tiers) restricting prepared statements.
Related errors
- failed to prepare read 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/dd029eef8e81e3d4.
Report an issue: GitHub.