jackc/pgx · error

hstore pair

Error message

hstore pair %d: %w

What it means

While parsing a binary hstore, reading the key/value pair at index %d failed (length header or data read error, wrapped with %w from the pgio reader). The malformed binary hstore payload from the server is at fault.

Solutions

  1. Inspect the wrapped error for the precise read failure
  2. Treat the wire data as corrupted and re-fetch the row
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pgtype/hstore.go:205 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /api/errors/944cf47722a7b461. Report an issue: GitHub.

Appendix: source

Thrown at pgtype/hstore.go:205

	r := pgio.NewReader(src)

	// Each pair carries at minimum two int32 length headers (key, value). This bounds the
	// up-front make() against a malicious server claiming a huge pair count in a small message.
	pairCount := r.Count(8)
	if err := r.Err(); err != nil {
		return fmt.Errorf("hstore: %w", err)
	}

	hstore := make(Hstore, pairCount)
	// one allocation for all *string, rather than one per string, just like text parsing
	valueStrings := make([]string, pairCount)

	for i := range pairCount {
		keyBytes, keyNull := r.Value()
		valueBytes, valueNull := r.Value()
		if err := r.Err(); err != nil {
			return fmt.Errorf("hstore pair %d: %w", i, err)
		}
		if keyNull {
			return fmt.Errorf("hstore pair %d: key cannot be NULL", i)
		}

		key := string(keyBytes)
		if valueNull {
			hstore[key] = nil
		} else {
			valueStrings[i] = string(valueBytes)
			hstore[key] = &valueStrings[i]
		}
	}

	if err := r.Finish(); err != nil {
		return fmt.Errorf("hstore: %w", err)
	}
	return scanner.ScanHstore(hstore)

View on GitHub (pinned to ec1a0befd2)