NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules
Last release today
28 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 34 of 34 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
442 releases · first in 2021
One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
This release adds direct PostgreSQL type scanning through database/sql on Go 1.27, improves compatibility with libpq connection strings and PostgreSQL
This release adds direct PostgreSQL type scanning through database/sql on Go 1.27, improves compatibility with
libpq connection strings and PostgreSQL date/time values, and includes further decoder hardening. See Changes for
connection-string and date/time behavior changes that may affect existing applications.
driver.RowsColumnScanner, allowing PostgreSQL types such as arrays and ranges to bepgtype.Map.SQLScanner. Existing database/sql scalar conversions andsql.Scanner behavior are preserved. The minimum supported Go version remains 1.25.Rows.TypeMap to expose the type map used to decode rows, including rows created by RowsFromResultReaderConn. Custom implementations of Rows, including mocks, must add this method.Config.MaxProtocolMessageBodyLen to configure the maximum incoming protocol message body sizeErrReadOnlyConnection, ErrReadWriteConnection, ErrPrimaryConnection, and ErrStandbyConnectiontarget_session_attrs validation, allowing callers to use errors.Is (Adrian-Stefan Mares)pool_ping_timeout in connection strings to configure Config.PingTimeout. The default is zero;Name-based row-to-struct mapping now matches explicit db tags case-insensitively, with exact matches taking
precedence so tags can still distinguish quoted column names that differ only by case (AlisinaDevelo)
pgconn: resolve the OS user account only when no user is supplied by the connection string, environment, or service
file, avoiding unnecessary account lookups and crashes in some restricted container environments. Home-directory
defaults for password, service, and TLS files remain available independently of the account lookup. On Unix these
now use $HOME rather than the OS account's home directory (Mohamed MAACHE)
pgtype: date, timestamp and timestamptz text values are now parsed and written by a hand-written parser and
encoder for PostgreSQL's ISO date/time format instead of time.Parse and time.Format. Go's layout language cannot
express a variable-width year or the BC era, which is the root of the bugs below. The text scan path is roughly 2.5x
faster for timestamp and timestamptz. Bug fixes:
timestamp and timestamptz no longer silently move February 29 of a BC leap year to March 1 when encoding.time.Date(-4712, 2, 29, ...) was written as 4713-03-01 BC and is now written as 4713-02-29 BC. Thisdate was never affected.timestamp and timestamptz can now scan BC leap days. 4713-02-29 BC previously failed withday out of range. date could already scan them.10000-01-02 03:04:05 previously failed to parse, so timestamp andtimestamptz values at the high end of PostgreSQL's range were unreadable over the simple protocol and in anytime.Time arguments in the simple protocol now encode BC dates correctly, using the same timestamp encoder.Behavior changes:
date now rejects impossible dates instead of normalizing them. 2024-02-30 returned 2024-03-01 and2024-13-01 returned 2025-01-01; both are now errors. timestamp and timestamptz already rejected them.QueryExecMode.timestamptz also rejects time zone displacements outside PostgreSQL's signed 32-bit seconds range, while accepting+16.timestamptz values scanned from the text format are now returned in time.Local, or in ScanLocation when it istime.Parse derived from the offset the server sent, so the same value scanned in the two formats could report aLocation() and Zone(). The instant is unchanged, but everything that renders the location changesTimestamptz.MarshalJSON now writes the client's offset rather than the server's, so a value the server+05:30 marshals as 2024-01-01T13:34:05-08:00 on a UTC-8 client instead of 2024-01-02T03:04:05+05:30,DecodeDatabaseSQLValue hands database/sql a time.Time in that same location. Set the codec'sScanLocation to time.UTC to pin the location regardless of the client's zone.pgconn: connection URIs (postgres://...) are now parsed by a new parser designed to exactly match libpq's URI
parser behavior instead of net/url,
making pgx accept and reject exactly the same URIs as libpq (verified by differential fuzzing against libpq itself).
Most connection strings are unaffected. Edge-case behavior changes, all matching libpq:
+ in query values is literal, no longer decoded as a space.%00 is rejected.%20).# is ordinary data, not a fragment delimiter.@ before any / (previously the last @).ssl=true is accepted as an alias for sslmode=require in URIs (JDBC compatibility). A repeated ssl keysslmode. Ifssl value is not true, an independent explicit sslmode remains in effect.postgres://h1,h2:5433/db now means h1:5432 andcould not match N port numbers to M hosts), also for keyword/value connection strings.postgres://::1/db was previously accepted as host::1; it is now read as an empty host followed by port :1 and fails with an invalid port error. Write it aspostgres://[::1]/db.h1,,h2) get the default host instead of being dropped. Likewise, an empty host inhost=) now means the default host -- typically the Unix socket directory -- where it?port= in a URI or port= in a keyword/value string) now means the default port 5432 for thePGPORT.net/urlnet/url did.Unlike libpq, unrecognized URI query parameters are still accepted (they become runtime parameters or pgx-specific
options). Parse error messages avoid quoting the unredacted connection string and redact recognizable password
fields on a best-effort basis. Invalid connection strings can be structurally ambiguous, so password redaction
cannot be guaranteed for every malformed input.
pgconn: keyword/value connection strings (host=... user=...) now match libpq's parser exactly, the same treatment
the URI parser received above and verified the same way, by differential fuzzing against libpq itself. Most
connection strings are unaffected. Behavior changes, all matching libpq:
\\ and \' weresslcert=C:\path\to\cert reads as C:pathtocert and has to be written sslcert=C:\\path\\to\\cert.invalid backslash. Inside a quoted value the escaped terminator leavesmissing "=" after "us" in connection info string) instead of becoming= is unaffected. This most often shows up with an unquoted valueapplication_name=my app host=x previously set neither parameter and sent app host to theAs with URIs, unrecognized keywords are still accepted where libpq rejects them, and an empty user= is still
dropped so that PGUSER and the OS user still apply.
Begin or BeginTxTraceQueryEnd when Exec fails while deallocating invalidated cached statements (Chris Bandy)LoadTypes overwriting scalar codecs such as box and point with an incorrect ArrayCodec (Arsen Ozhetov)FETCH statements,Batch.ExecStatement is mixed with other batch commands; preserve field descriptions for empty resultsPipeline.GetResults on errorMaxConnLifetime values as unlimited instead of immediately expiring connectionsArrayCodec.Delimiter, including the semicolon delimiterbox[]. LoadType and LoadTypes now load the delimiter from PostgreSQL (Sueun Cho)Numeric.ScanScientific and accept scientific notation inNumeric.UnmarshalJSON; reject out-of-range scientific exponents and preserve the original input in parse errors"Infinity" and "-Infinity" instead of encoding it as zeroNumeric with a nil Int as zero in Int64Value, and return errors when converting NaN orbit / varbit bit lengths against the actual data (g3m0sis).slice bounds out of range. host='a\ -- and the shorter ='\, reachable through pgx.ParseConfig andpgxpool.ParseConfig -- now return unterminated quoted string in connection info string, libpq's own message forpassword and sslpassword values suppliedpass%77ord= are recognized -- and masks the entire raw value, soParseConfigOptions.ConnStringAllowedKeys no longer exempts an explicitly supplied empty port (?port= inport= in a keyword/value string) from the allow-list. Only the implied all-empty port list of apostgres://h1,h2/db) is exempt. An explicit empty port shadows PGPORT even thoughssl=true alias is accepted whenssl or sslmode is allowed, and every ssl/sslmode spelling written in the URI is validated --asyncClose so context cancellation produces a TCP FIN instead of RST, avoiding "connection reset by peer" on the server / proxy (Sean Chittenden at CrowdStrike, Inc.)StartupMessage.Encode rejects a NUL byte in any parameter name or value instead of writing it. Theapplication_name ofx\x00user\x00admin changed the role the connection logged in as. libpq cannot reach this state because itsConnect now fails with nothing written to the wire, which coversConfig.RuntimeParams,Config.User, or Config.Database.ParseConfig, as URIs already were.Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Update changelog for v5.10.0
Update changelog for v5.10.0
This release includes a significant amount of hardening against malicious or compromised PostgreSQL servers,
contributed by Sean Chittenden at CrowdStrike, Inc. This work bounds binary decoders against attacker-controlled
message sizes, caps server-supplied SCRAM iteration counts, adds require_auth to restrict which authentication
methods a server may use (mitigating downgrade attacks under sslmode=prefer), and ensures cancellation requests are
sent over TLS when the original connection used TLS.
require_auth to restrict accepted server authentication methods (Sean Chittenden at CrowdStrike, Inc.)ParseConfigOptions.ConnStringAllowedKeys to restrict allowed connection string keys (Sean Chittenden at CrowdStrike, Inc.)StructArgs and StrictStructArgs for @-named queries (Tubelight30)ErrConnClosed sentinel error and unwrap it from connLockError (Charlie Tonneslan)CancelRequest connection when the primary connection used TLS (Sean Chittenden at CrowdStrike, Inc.)"char" (OID 18) into *string in binary format (luongs3)driver.Valuer in array and composite codecs (Donncha Fahy)CopyData.Data hex decoding in UnmarshalJSON (Charlie Tonneslan)parseKeywordValueSettings rejecting trailing whitespace (alliasgher)normalizeTimeoutError (Charlie Tonneslan)connectPreferred (Charlie Tonneslan)MaxLifetimeDestroyCount and ping order for acquire-time expiry checkrows.Err to load types (Jen Altavilla)Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Fix SQL Injection via placeholder confusion with dollar quoted string literals (GHSA-j88v-2chj-qfwx)
Fix SQL Injection via placeholder confusion with dollar quoted string literals (GHSA-j88v-2chj-qfwx)
SQL injection can occur when:
e.g.
attackValue := `$tag$; drop table canary; --`
_, err = tx.Exec(ctx, `select $tag$ $1 $tag$, $1`, pgx.QueryExecModeSimpleProtocol, attackValue)
This is unlikely to occur outside of a contrived scenario.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Fix: batch result format corruption when using cached prepared statements (reported by Dirkjan Bussink)
This release includes a number of new features such as SCRAM-SHA-256-PLUS support, OAuth authentication support, and PostgreSQL protocol 3.2 support.
This release includes a number of new features such as SCRAM-SHA-256-PLUS support, OAuth authentication support, and PostgreSQL protocol 3.2 support.
It significantly reduces the amount of network traffic when using prepared statements (which are used automatically by default) by avoiding unnecessary Describe Portal messages. This also reduces local memory usage.
It also includes multiple fixes for potential DoS due to panic or OOM if connected to a malicious server that sends deliberately malformed messages.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →