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

You spin up a Kubernetes workload. You connect to PostgreSQL.

You add `sslmode=require` because security matters.

And then PostgreSQL replies with:

```plaintext
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.

## The Setup

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:

```plaintext
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser sslmode=require"
```

And PostgreSQL responded:

```plaintext
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?

* * *

## What `sslmode=require` Actually Does

When you set:

```plaintext
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:

![](https://cdn.hashnode.com/uploads/covers/68fb4c09020910660a830e8f/cc741a68-29e8-4128-8221-7671bdaf334c.png align="center")

If the server is not configured with SSL enabled, the handshake never happens and the client exits.

That is exactly what happened here.

* * *

## Why This Happens in Kubernetes Environments

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.

## Step 1: Confirm Whether the Server Supports SSL

Before changing anything, verify the server configuration.

If you can connect without SSL, try:

```plaintext
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:

```plaintext
SHOW ssl;
```

If it returns:

```plaintext
ssl | off
```

then the error makes complete sense.

* * *

## Step 2: Understand Your Architecture

Here is the real question:

Should SSL even be required here?

Look at the traffic path.

![](https://cdn.hashnode.com/uploads/covers/68fb4c09020910660a830e8f/68b346b0-eff4-4877-ab9c-1019ab30223e.png align="center")

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.

* * *

## Step 3: The Two Real Fixes

There are only two correct solutions.

### Option One: Disable SSL on the Client

If this is an internal trusted network, change:

```plaintext
sslmode=require
```

to:

```plaintext
sslmode=disable
```

or simply remove the parameter.

Test:

```plaintext
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:

```go
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
```

Then update pg\_hba.conf:

/code

Restart PostgreSQL.

Now test:

```go
psql "host=10.1.1.17 port=5432 dbname=mydb user=myuser sslmode=require"
```

And confirm:

```go
SELECT ssl_is_used();
```

If it returns true, the handshake succeeded.

The flow now looks like this:

![](https://cdn.hashnode.com/uploads/covers/68fb4c09020910660a830e8f/05d539b2-6fc3-4428-ac1d-bb2ec28067b8.png align="center")

That is the correct configuration if encryption is part of your compliance or security requirement.

* * *

## A Common Hidden Cause in Cloud Environments

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.

## Practical Debug Checklist

Whenever you see this error, follow this mental model:

![](https://cdn.hashnode.com/uploads/covers/68fb4c09020910660a830e8f/a5b3fce1-27e9-4a9d-a36c-65d7e302cfde.png align="center")

Keep it simple.

Test the network first. Then test without SSL.

Then make an intentional security decision.

* * *

## Lessons Learned

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.

* * *

## Final Thought

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.
