Grease
[TODO: In-progress landing page for the 19beta grease campaign. Should be made a protected page. This is not yet "blessed" by the project.]
You're likely here because you're beta-testing PostgreSQL 19, and you've seen an error of the form
connection to server at "pg.example.com", port 5432 failed: server [...did something...]
This indicates a bug in either the server being contacted
or a proxy handling the connection. Please consider
reporting this to the maintainers of that software.
For more information, including instructions on how to
work around this issue for now, visit
https://www.postgresql.org/...
That is a "grease error", and this page should help explain what that is.
(If you're a developer who's been sent this page, there's a section for you further down.)
Q&A for Users
What's going on?
For the PG19 beta cycle, PostgreSQL client software will be stricter than usual when connecting to servers. If we notice that a server isn't following the "rules" during a connection, we'll stop and let you know instead of silently continuing.
What do I need to do?
The most important thing is to find the people who maintain the database that you're trying to connect to, send them the error message that you got, and ask them to fix it. Send them a link to this page if they're confused.
If you have extra time, and there are no privacy or legal concerns in doing so, you might send us a mail telling us that you hit this error. We won't be able to fix it for you, but we might know the people who can, and in any case it's useful for us to know that the grease campaign is doing its job.
Okay, but how do I keep testing now?
Once you've reported the issue, you can temporarily add max_protocol_version=3.0 to your connection string, or set PGMAXPROTOCOLVERSION=3.0 in your environment, to return to the standard client behavior and connect again. Remember to remove this once we're out of beta!
Q&A for Developers
What's going on?
You maintain server or proxy software that speaks the PostgreSQL network protocol, and our software is pretty sure that your software isn't negotiating connection parameters correctly.
If the situation doesn't change, a future Postgres release is likely to break compatibility with you, possibly in a very confusing way, so we want you to know about the problem sooner rather than later. For now, though, this stricter behavior will only be enabled during the PG19 beta period.
(This is not an indictment of you or your software. The libpq library itself didn't understand negotiation for something like five years after negotiation was introduced; whoops. But if we don't start requiring stricter behavior at some point, we're not going to be able to make many protocol improvements in practice.)
What are these connection parameters?
The parameters in question are the minor version and any protocol extensions.
Our protocol, somewhat unusually, requires a server to opt out of features it does not understand instead of opting into the ones it does. If a client requests a 3.x minor version that is greater than the version you support (which is likely 3.0), you must send a NegotiateProtocolVersion message, containing the actual version in use, in response to the startup message. If a client requests protocol extensions you do not understand (which is any protocol extension, since we haven't defined any as of 2026), you must send those in the NegotiateProtocolVersion message as well.
Then continue the handshake. Don't error out when the client asks for something you don't know; tell the client you won't use it, and move on. Our protocol documentation contains more information.
I think I'm following the rules, though?
We've tried hard to make this check as conservative as possible, but if you're pretty sure that you're seeing a false positive, please let us know about it right away so we can fix it. We want this campaign to be high-signal, low-noise.
Do I have to fix this by the PG19 release?
No. We'll revert this strict grease behavior before our planned release in late 2026. This is a beta-only check for now.
However! A future release (PG20+) may enable some parts of this check in production, depending on how the PG19 campaign goes, so please plan accordingly.
What is "Grease"?
The practice of sending negotiation parameters that should be ignored, and failing if they are not. The name itself is a metaphor/in-joke among protocol designers.
Protocol negotiation was introduced to Postgres in 2017, but we have yet to use it by default. Since then, we've identified implementations that attempted to implement negotiation but did so incorrectly; there are others that don't implement it at all. Even after those implementations are fixed, we have no way to know whether the fixed versions are the ones being used in production. So the community has gotten stuck: afraid to introduce new protocol features for fear of breakage, but knowing that every year we wait, the inaction leads to more ossification.
To put it another way, we commonly build "joints" into network protocols, with the hope that we'll use them for extensibility in the future. But if we don't actually use them for a long time, widely-used implementations may ignore them, and those joints will "rust" in place.
TLS, which has famously run into several compatibility issues during version upgrades, named its solution to this problem GREASE to continue the metaphor. The name "grease" is now a more general term of art.