Guides / FATAL: no pg_hba.conf entry ... no encryption (Postgres SSL required)

FATAL: no pg_hba.conf entry ... no encryption (Postgres SSL required)

Your managed Postgres (RDS, Heroku Postgres, Azure, Neon and others) refuses the connection with FATAL: no pg_hba.conf entry for host "203.0.113.5", user "app", database "app", no encryption. The database requires an encrypted connection, and Django connected without one. Set sslmode in your database options.

django.db.utils.OperationalError: connection to server at "db.example.com" (203.0.113.9), port 5432 failed:
FATAL:  no pg_hba.conf entry for host "203.0.113.5", user "app", database "app", no encryption

What it means

The server's access rules (pg_hba.conf) only accept hostssl connections from your address, and your client tried a plain one. Related messages mean the opposite or a trust problem: server does not support SSL, but SSL was required (you asked for SSL, the server has none, typical for a local Postgres) and SSL error: certificate verify failed (you asked to verify, and it can't).

Why it happens

  1. Managed Postgres requires SSL, but DATABASES has no SSL option. Local Postgres didn't need one, so it worked in development.
  2. Your DATABASE_URL lacks ?sslmode=require, and the library doesn't add it.
  3. You require a certificate check (verify-full) without giving the client the provider's CA certificate.
  4. SSL is forced everywhere, including local development against a Postgres without SSL.

The fix

In DATABASES, pass sslmode through OPTIONS (psycopg2 and psycopg 3 both accept it):

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.environ["DB_NAME"],
        "USER": os.environ["DB_USER"],
        "PASSWORD": os.environ["DB_PASSWORD"],
        "HOST": os.environ["DB_HOST"],
        "PORT": os.environ.get("DB_PORT", "5432"),
        "OPTIONS": {"sslmode": os.environ.get("DB_SSLMODE", "require")},
    }
}

If you use a connection URL, add it to the URL, or use dj-database-url's helper:

export DATABASE_URL="postgres://USER:PASSWORD@db.example.com:5432/NAME?sslmode=require"
DATABASES = {"default": dj_database_url.config(env="DATABASE_URL", ssl_require=True)}

Which sslmode?

"OPTIONS": {"sslmode": "verify-full", "sslrootcert": "/app/certs/global-bundle.pem"},

For local development against a Postgres without SSL, use DB_SSLMODE=prefer (or disable) in your .env, which is why the example reads it from the environment.

Making it stick in production

Or skip it

With Django Cloud you add a managed Postgres database from the dashboard and your app is connected to it, so there is no database host or port to wire up yourself.

pip install djangocloud-cli
djangocloud deploy

Get startedSee pricing

Free plans are available for students, AWS Activate startups, open-source, non-profit and research projects. See how Django Cloud compares with other ways to host Django.

Django is a registered trademark of the Django Software Foundation. Django Cloud is not affiliated with or endorsed by it. Found a mistake in this guide? Tell us and we will fix it.