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

  1. Check the wrapped cause for a MySQL error code (connection vs syntax)
  2. Verify database/table names form valid identifiers
  3. Recreate the store or call configure again to reopen the connection
  4. 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

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


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