Skip to content
PostgreSQL ODBC Driver: Install and Configure

Click to use (opens in a new tab)

PostgreSQL ODBC Driver: Install and Configure

August 25, 2026 by Chat2DBChat2DB Team

ODBC is how a long tail of software talks to databases: Excel, Access, Power BI's legacy connectors, Tableau extracts, SSIS packages, MATLAB, SAS, and countless internal tools written before anyone had heard of a REST API. When that software needs PostgreSQL, it needs psqlODBC — the official PostgreSQL ODBC driver. This guide covers installing it on all three platforms, setting up DSNs, writing DSN-less connection strings, enabling TLS, and decoding the error messages that send people in circles.

What psqlODBC actually is

ODBC has three layers. Your application calls the driver manager (ODBC Data Source Administrator on Windows, unixODBC or iODBC elsewhere), the driver manager loads the driver (psqlODBC), and the driver speaks the PostgreSQL wire protocol to the server. A DSN (Data Source Name) is just a saved bundle of driver plus connection settings.

psqlODBC ships two variants:

  • ANSI (psqlodbca) — legacy 8-bit encodings, for old applications.
  • Unicode (psqlodbcw) — UTF-16 on the API surface, correct for anything modern.

Choose Unicode unless you have a specific reason not to. Mixing them is a classic source of mojibake in non-English data.

The other axis is bitness. A 32-bit application requires a 32-bit driver even on 64-bit Windows, and they are administered by different tools. This one detail accounts for a large share of "driver not found" reports.

Windows

Download the installer from the PostgreSQL ODBC download page (psqlodbc_x64.zip or psqlodbc_x86.zip) — the EDB Stack Builder that ships with the Windows PostgreSQL installer can also fetch it under Database Drivers → psqlODBC.

After installing, open the right administrator:

  • 64-bit: C:\Windows\System32\odbcad32.exe (or search "ODBC Data Sources (64-bit)")
  • 32-bit: C:\Windows\SysWOW64\odbcad32.exe

Yes, System32 holds the 64-bit tool and SysWOW64 the 32-bit one. That is not a typo; it is a Windows historical artefact.

Create the DSN:

  1. Choose the System DSN tab if a service or scheduled task will use it, User DSN if only your login needs it. Services run as another account and cannot see your User DSNs — this is the second-most-common configuration mistake.
  2. Click Add, pick PostgreSQL Unicode(x64).
  3. Fill in the fields:
FieldValue
Data Sourceanalytics_prod (the DSN name your app will use)
Databaseanalytics
Serverdb.internal.example.com
Port5432
User Namereport_reader
Password(stored in the registry — see the note below)
SSL Moderequire or stronger
  1. Click Test before saving.

Passwords in a DSN are stored obfuscated, not encrypted, in the registry under HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI. Treat them as recoverable by anyone with access to that account. For anything sensitive, leave the password blank in the DSN and supply it in the connection string at runtime, or use a .pgpass-style credential store on the application side.

Useful Datasource options

The Datasource button opens the settings that actually affect behaviour:

  • Use Declare/Fetch with Cache Size — fetches rows in batches instead of pulling the entire result set into memory. Essential for large queries; the default of 100 is conservative but safe.
  • Max Varchar / Unknown Sizes — how the driver reports the length of unbounded text columns. Some applications (Excel, Access) allocate buffers based on this and will truncate or refuse data if it is wrong. If text columns come back cut off at 255 characters, raise Max Varchar or set Unknown Sizes to "Maximum".
  • Text as LongVarChar — controls whether text maps to SQL_LONGVARCHAR or SQL_VARCHAR. Access prefers the latter for editable tables.
  • Bools as Char — MS Access needs booleans mapped to char to display them properly.
  • Level of rollback on errorsTransaction (default) rolls back the whole transaction on any error; Statement rolls back only the failing statement, which is what most applications expect.
  • Server side prepare — on by default and generally good; disable it if you hit prepared statement "..." already exists behind a transaction-pooling connection pooler.

macOS

Install the driver manager and driver with Homebrew:

brew install unixodbc psqlodbc

Homebrew registers the driver automatically in most cases. Verify:

odbcinst -j          # shows the paths of odbc.ini and odbcinst.ini
odbcinst -q -d       # lists installed drivers

If the driver is not listed, register it manually. Create /opt/homebrew/etc/odbcinst.ini:

[PostgreSQL Unicode]
Description = PostgreSQL ODBC driver (Unicode)
Driver      = /opt/homebrew/lib/psqlodbcw.so
UsageCount  = 1

On Intel Macs the prefix is /usr/local instead of /opt/homebrew.

Then define a DSN in ~/.odbc.ini:

[analytics_prod]
Description = Analytics production
Driver      = PostgreSQL Unicode
Servername  = db.internal.example.com
Port        = 5432
Database    = analytics
Username    = report_reader
SSLmode     = require

Test it:

isql -v analytics_prod report_reader 'the-password'

isql is unixODBC's equivalent of psql — if it connects, the driver stack is fine and any remaining problem is in the application.

Linux

On Debian/Ubuntu:

sudo apt-get install unixodbc odbc-postgresql

On RHEL/Rocky/Alma:

sudo dnf install unixODBC postgresql-odbc

The packages usually register the driver in /etc/odbcinst.ini:

[PostgreSQL Unicode]
Description = PostgreSQL ODBC driver (Unicode version)
Driver      = /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
Setup       = /usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so
UsageCount  = 1

System-wide DSNs go in /etc/odbc.ini, per-user ones in ~/.odbc.ini, with the same keys as the macOS example. Confirm with odbcinst -q -d and isql -v <dsn>.

If you are running inside a container, remember that unixodbc and the driver must both be installed in the image, and SELinux on RHEL derivatives can block the driver from opening network sockets — setsebool -P httpd_can_network_connect_db 1 is the usual fix for web workloads.

DSN-less connection strings

DSNs are convenient interactively and painful to deploy. Most applications accept a full connection string instead, which keeps configuration with the application:

Driver={PostgreSQL Unicode};Server=db.internal.example.com;Port=5432;Database=analytics;Uid=report_reader;Pwd=secret;sslmode=require;

On Linux/macOS, reference the driver by the name registered in odbcinst.ini, or by absolute path:

Driver=/usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so;Server=...;

From Python with pyodbc:

import pyodbc
 
conn = pyodbc.connect(
    "Driver={PostgreSQL Unicode};"
    "Server=db.internal.example.com;Port=5432;"
    "Database=analytics;Uid=report_reader;Pwd=secret;"
    "sslmode=require;",
    autocommit=True,
)
cur = conn.cursor()
cur.execute("SELECT version()")
print(cur.fetchone()[0])

Useful extra keywords: ReadOnly=1 to guard a reporting connection, ConnSettings=SET+search_path+TO+reporting to set session parameters at connect time (spaces are encoded as +), and Fetch=1000 to tune the declare/fetch batch size.

TLS

Set sslmode explicitly — the defaults across driver versions are not consistent enough to rely on:

ModeEncryptionServer certificate verified
disableNo
allow / preferOpportunisticNo
requireYesNo
verify-caYesSigned by a trusted CA
verify-fullYesCA and hostname match

require only guarantees the traffic is encrypted; it does not stop a man-in-the-middle from presenting any certificate. For connections crossing an untrusted network, use verify-full and point the driver at the CA bundle:

sslmode=verify-full;sslrootcert=C:\certs\rds-ca-bundle.pem;

Managed platforms publish their CA bundles — AWS RDS, Azure Database for PostgreSQL and Cloud SQL each have a documented root certificate you should pin.

Common errors and what they mean

Data source name not found and no default driver specified — nine times out of ten this is a bitness mismatch: a 32-bit application looking for a DSN created in the 64-bit administrator (or vice versa). Recreate the DSN in the matching tool. It is also what you get when a Windows service tries to use a User DSN.

Can't open lib '/usr/lib/.../psqlodbcw.so' : file not found — the path in odbcinst.ini is wrong, or a dependency of the driver is missing. Check with ldd /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so | grep 'not found'.

FATAL: no pg_hba.conf entry for host ... — the driver reached the server and the server refused the connection. Add a matching line to pg_hba.conf and reload; if it mentions "no encryption", the entry requires SSL and the client did not use it.

FATAL: password authentication failed with correct credentials — often scram-sha-256 against a driver too old to support it. psqlODBC has supported SCRAM since 10.x; upgrade the driver rather than downgrading the server's authentication method.

Received unexpected message type 'v' — the same SCRAM incompatibility, seen through a connection pooler.

Text truncated at 255 characters — the Max Varchar / Unknown Sizes setting discussed above.

prepared statement "..." already exists — server-side prepared statements colliding behind a transaction-pooling PgBouncer. Either switch the pooler to session pooling or disable Server side prepare in the DSN.

Everything is slow, and pg_stat_activity shows the query finishing fast — the driver is materialising the entire result set. Enable Use Declare/Fetch with a cache size of a few thousand rows.

Do you actually need ODBC?

ODBC exists to serve applications that only speak ODBC. If you are writing new code, the native drivers are faster and simpler: psycopg for Python, JDBC for the JVM, pgx for Go, node-postgres for Node. If you just want to browse tables and run queries against Postgres, a native client avoids the whole driver-manager layer — Chat2DB (opens in a new tab) is a free AI-powered SQL client that connects directly with a host, port, database and user, and there is a browser version at app.chat2db.ai (opens in a new tab) if you would rather not install a driver stack at all.

Summary

Install psqlODBC in the Unicode variant with the bitness that matches your application, register it with the platform's driver manager, and test the stack with the administrator's Test button or isql before blaming the application. Prefer DSN-less connection strings for anything deployed, set sslmode explicitly (verify-full across untrusted networks), enable declare/fetch for large result sets, and remember that the two configuration mistakes behind most failures are bitness mismatches and User-versus-System DSN confusion.