micro/go-micro · error

sqlStore.read failed

Error message

sqlStore.read failed

What it means

The legacy postgres store's read function executes the query (exact key or pattern) and wraps failures with 'sqlStore.read failed'. sql.ErrNoRows is treated as an empty result, so this error means the query itself failed, not that the key is missing. Callers: Read (single-key reads).

Source

Thrown at store/postgres/postgres.go:475

			return nil, err
		}
		defer st.Close()

		rows, err = st.Query(pattern, options.Limit, options.Offset)
	} else {
		st, err = s.prepare(options.Database, options.Table, "readMany")
		if err != nil {
			return nil, err
		}
		defer st.Close()

		rows, err = st.Query(pattern)
	}
	if err != nil {
		if err == sql.ErrNoRows {
			return []*store.Record{}, nil
		}
		return []*store.Record{}, errors.Wrap(err, "sqlStore.read failed")
	}

	defer rows.Close()

	records, err := s.rowsToRecords(rows)
	if err != nil {
		return nil, err
	}
	rowErr := rows.Close()
	if rowErr != nil {
		// transaction rollback or something
		return records, rowErr
	}
	if err := rows.Err(); err != nil {
		return records, err
	}

	return records, nil

View on GitHub (pinned to 24529f1404)

Solutions

  1. Check the wrapped driver error for the root cause (connection vs syntax vs timeout).
  2. Confirm the table exists and the store was initialized against the right database.
  3. Retry on transient connection errors; enable connection health checks (db.SetConnMaxLifetime).
  4. Validate/escape keys used in pattern queries.
  5. Verify read privileges on the table for the DB user.

Example fix

// before
recs, err := s.Read("user:1; DROP") // unsafe pattern chars
// after
if !validKeyPattern(key) { return nil, ErrInvalidKey }
recs, err := s.Read(key)
Defensive patterns

Strategy: retry

Validate before calling

// before read
if key == "" { return ErrEmptyKey }
if strings.ContainsAny(key, "%'\\;") { return ErrInvalidKeyPattern }
if err := db.Ping(); err != nil { // refresh connection }

Type guard

func isReadErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "sqlStore.read failed") && !errors.Is(err, sql.ErrNoRows)
}

Try / catch

recs, err := store.Read(key)
if err != nil {
	if isTransientNetErr(err) {
		return retryWithBackoff(func() error { _, err = store.Read(key); return err })
	}
	return err // missing keys return empty slice + nil, not this error
}

Prevention

When it happens

Trigger: Calling store.Read with a key when the SELECT fails: connection errors, table missing (initialization skipped or dropped), invalid SQL pattern characters, statement timeouts, or rowsToRecords scanning issues after query execution.

Common situations: Database restarted or connection pool stale; schema changed out-of-band (table dropped); special characters in keys breaking LIKE patterns; long queries hitting statement_timeout on managed Postgres.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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