micro/go-micro · error

Couldn't insert record ${key}

Error message

Couldn't insert record ${key}

What it means

The legacy postgres store's Write method executes the upsert statement (with expiry or NULL) and wraps failures with 'Couldn't insert record <key>'. Like its pgx counterpart, this indicates the database rejected the INSERT/UPSERT for the given key.

Source

Thrown at store/postgres/postgres.go:531

	metadata := make(Metadata)
	for k, v := range r.Metadata {
		metadata[k] = v
	}

	var expiry time.Time
	if r.Expiry != 0 {
		expiry = time.Now().Add(r.Expiry)
	}

	if expiry.IsZero() {
		_, err = st.Exec(r.Key, r.Value, metadata, nil)
	} else {
		_, err = st.Exec(r.Key, r.Value, metadata, expiry)
	}

	if err != nil {
		return errors.Wrap(err, "Couldn't insert record "+r.Key)
	}

	return nil
}

// Delete records with keys
func (s *sqlStore) Delete(key string, opts ...store.DeleteOption) error {
	var options store.DeleteOptions
	for _, o := range opts {
		o(&options)
	}

	// create the db if not exists
	if err := s.createDB(options.Database, options.Table); err != nil {
		return err
	}

	st, err := s.prepare(options.Database, options.Table, "delete")

View on GitHub (pinned to 24529f1404)

Solutions

  1. Inspect the wrapped driver error to distinguish constraint/permission/connection causes.
  2. Verify the DB user has INSERT and UPDATE privileges on the table.
  3. Retry transient failures with backoff; ensure the table exists (re-run configure).
  4. Reduce record value size or increase column capacity if limits are hit.
  5. Check for conflicting concurrent writers to the same key.

Example fix

// before
st, _ := db.Prepare(writeStmt)
_, err := st.Exec(key, hugeValue, metadata, expiry) // value > 1GB limit
// after
if len(value) > maxValueSize { return ErrValueTooLarge }
_, err := st.Exec(key, value, metadata, expiry)
Defensive patterns

Strategy: retry

Validate before calling

// before write
if r.Key == "" || len(r.Value) > maxByteaSize { return ErrInvalidRecord }
if err := db.Ping(); err != nil { // reconnect }

Type guard

func isInsertErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "Couldn't insert record")
}

Try / catch

err := store.Write(rec)
if err != nil {
	if isInsertErr(err) && isTransientNetErr(err) {
		return retryWithBackoff(func() error { return store.Write(rec) })
	}
	return err
}

Prevention

When it happens

Trigger: Calling store.Write when the prepared statement's Exec fails: constraint violations, connection failure, value exceeding bytea/field limits, invalid metadata JSON marshaling already consumed upstream, or table missing.

Common situations: Connection pool exhaustion under load; oversized record values; DB user lacking INSERT/UPDATE privileges; server clock skew affecting expiry timestamps; primary key conflicts on concurrent writes to the same key when the DDL lacks ON CONFLICT coverage.

Related errors


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