When SSL Lies: Debugging PostgreSQL “server does not support SSL” in Kubernetes

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Search for a command to run...

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
No comments yet. Be the first to comment.
Artificial Intelligence has become one of the biggest talking points in software engineering. Every week, a new tool promises to automate deployments, fix production incidents, or replace developers a

When you first approach Tencent Cloud, it feels familiar if you come from AWS or Azure. There are VPCs, Kubernetes clusters, load balancers, object storage, IAM, everything you would expect. But once

When I first automated Docker builds and deployments, I thought the hard part would be writing the YAML. It was not. The real challenges were versioning, preventing accidental rollbacks, handling envi

For a long time, Docker Compose felt like the perfect solution. Simple YAML, fast local setup, predictable behavior. For a single service or even a small stack, it works beautifully. But at some point, reality catches up. As the application grew, tra...

CodeOps Studies
40 posts
Simple write-ups on day to day code or devops experiments, tests etc.
You spin up a Kubernetes workload. You connect to PostgreSQL.
You add sslmode=require because security matters.
And then PostgreSQL replies with:
server does not support SSL, but SSL was required
Wait. What?
This is one of those errors that sounds like a configuration typo but usually reveals something deeper about your infrastructure. Let’s break it down properly and fix it the right way.
This was a fairly common environment:
Application running inside Kubernetes
PostgreSQL running on a private IP inside the VPC
Direct psql access used for testing connectivity
Connection string explicitly enforcing SSL
The test command looked like this:
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser sslmode=require"
And PostgreSQL responded:
psql: error: connection to server at "10.1.1.17", port 5432 failed:
server does not support SSL, but SSL was required
At first glance, it feels contradictory. PostgreSQL supports SSL. So why is it saying it does not?
sslmode=require Actually DoesWhen you set:
sslmode=require
you are telling the PostgreSQL client:
If SSL cannot be negotiated, fail immediately.
No fallback. No downgrade. No retry without encryption.
The connection flow looks like this:
If the server is not configured with SSL enabled, the handshake never happens and the client exits.
That is exactly what happened here.
In many Kubernetes setups, PostgreSQL is:
A container inside the cluster
A VM inside a private subnet
An internal managed database
Or a local development database
In these cases, SSL is often disabled by default.
This creates a mismatch:
The client demands encryption
The server is configured for plain TCP
PostgreSQL refuses to downgrade
The connection fails
From PostgreSQL’s perspective, nothing is wrong. It simply does not have SSL enabled.
Before changing anything, verify the server configuration.
If you can connect without SSL, try:
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser sslmode=disable"
If that works, then the database is reachable and the issue is purely SSL related.
Now check whether SSL is enabled on the server:
SHOW ssl;
If it returns:
ssl | off
then the error makes complete sense.
Here is the real question:
Should SSL even be required here?
Look at the traffic path.
If all communication is happening:
Inside the same Kubernetes cluster
Or inside a private VPC
Without exposure to the public internet
then the network layer is already isolated.
In such cases, enforcing SSL is sometimes unnecessary and only adds complexity.
However, if the database is:
Publicly accessible
Cross region
Or accessed over the internet
then SSL should absolutely be enabled.
There are only two correct solutions.
If this is an internal trusted network, change:
sslmode=require
to:
sslmode=disable
or simply remove the parameter.
Test:
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser"
If it connects successfully, you are done.
This is common in:
Local development
Internal Kubernetes clusters
Private staging environments
Option Two: Enable SSL on PostgreSQL Properly
If encryption is required, then the server must be configured correctly.
In postgresql.conf:
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
Then update pg_hba.conf:
/code
Restart PostgreSQL.
Now test:
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser sslmode=require"
And confirm:
SELECT ssl_is_used();
If it returns true, the handshake succeeded.
The flow now looks like this:
That is the correct configuration if encryption is part of your compliance or security requirement.
There is one more subtle scenario.
Sometimes you are used to managed services like Amazon RDS where SSL is enabled automatically.
Then you switch to:
Self managed PostgreSQL
A container image
A VM based deployment
And assume SSL is still enabled.
It is not.
Managed database services often handle:
Certificate provisioning
Key rotation
TLS negotiation
Client CA bundles
Self managed PostgreSQL does none of that unless you configure it explicitly.
That assumption gap is where this error usually comes from.
Whenever you see this error, follow this mental model:
Keep it simple.
Test the network first. Then test without SSL.
Then make an intentional security decision.
The key takeaway is this:
Just because PostgreSQL supports SSL does not mean your server instance is configured for it. Blindly adding sslmode=require because it feels secure can actually break perfectly valid internal architectures.
Security is about understanding your network boundaries, not just toggling flags in connection strings. If traffic never leaves a private subnet, SSL might be optional.
If traffic crosses public infrastructure, SSL should be enforced and configured correctly.
The important part is intention.
This error is not PostgreSQL lying. It is PostgreSQL being honest.
It is simply telling you:
“I do not have SSL enabled, and you told me not to connect without it.”
Once you understand that, the fix becomes straightforward.
And like most infrastructure issues, the real problem was not PostgreSQL.
It was an assumption.