Edit

Frequently Asked Questions for ODBC on Linux and macOS

Download ODBC driver

This article answers common questions about installing, connecting with, and developing applications for the Microsoft ODBC Driver for SQL Server on Linux and macOS.

About the driver

Which ODBC driver version should I use?

Use Microsoft ODBC Driver 18 for SQL Server, the current driver line, for new development. Microsoft ODBC Driver 17 for SQL Server remains supported for applications that already deploy it, as described in the support lifecycle.

The upgrade change that affects most applications is that Driver 18 encrypts connections by default. For all the differences, see Major version differences.

Which operating systems and processor architectures does the driver support?

Driver 18 supports these operating systems and processor architectures:

Operating system x64 support Arm64 support
Alpine Linux Yes Starting with Driver 18.3
Azure Linux Yes Starting with Driver 18.6.1
Debian Yes Starting with Driver 18.1
Oracle Linux Yes No
Red Hat Enterprise Linux Yes Starting with Driver 18.1
SUSE Linux Enterprise Server Yes No
Ubuntu Yes Starting with Driver 18.1
macOS Yes Starting with Driver 17.8

The supported operating system versions change with each driver release. For the version-by-version table, see System requirements.

Which SQL Server features does the Linux and macOS driver support?

The driver on Linux and macOS supports most SQL Server features. It doesn't support distributed transaction enlistment through the SQL_ATTR_ENLIST_IN_DTC attribute, database mirroring, FILESTREAM, or the driver performance-profiling attributes. LocalDB isn't available on Linux or macOS. XA transactions through the Distributed Transaction Coordinator (DTC) are supported starting with Driver 17.3. For more information, see Use XA transactions with DTC. For the full list, see Limitations.

Is the driver open source?

No. The Microsoft ODBC Driver for SQL Server isn't open source.

Install and configure

Which driver manager does the driver use?

The driver uses the unixODBC driver manager. When you install Driver 17 or 18 with your platform's package manager or Homebrew, unixODBC installs as a dependency. Follow the steps for Linux or macOS.

On macOS, build and run your application with unixODBC rather than iODBC. Match the processor architecture of the application, driver manager, and driver. An error such as incompatible architecture (have 'arm64', need 'x86_64') indicates an architecture mismatch, not necessarily the wrong driver manager.

How do I check which drivers are installed and which configuration files are in use?

Run odbcinst -q -d to list the registered drivers. The output shows each driver name exactly as a connection string must spell it:

[ODBC Driver 18 for SQL Server]

Run odbcinst -j to show the unixODBC version and the paths of odbcinst.ini, which registers drivers, and odbc.ini, which holds system and user data source names (DSNs):

unixODBC 2.3.11
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/<user>/.odbc.ini

To configure a DSN, see Connection strings and DSNs.

Why does the driver manager report that it can't open the driver library?

The error looks like this:

[01000][unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server' : file not found

Check these causes in order:

  1. The Driver value in the connection string or DSN doesn't match a registered driver name. Run odbcinst -q -d and copy the name exactly.
  2. Your application uses different configuration files from the ones you edited. Run odbcinst -j from the same environment as the application and check which driver manager the application loads. On macOS, create configuration symbolic links only if the application needs them, as described in Troubleshooting on macOS.
  3. More than one copy of the unixODBC driver manager is installed, and your application loads the wrong one. On Linux, run find /usr -name 'libodbc*.so*'. On macOS, run find /opt/homebrew /usr/local -name 'libodbc*.dylib'. Multiple paths alone don't prove that multiple driver managers are installed: Homebrew links can point to the same library in its Cellar directory. Check which library the application actually loads. For more information, see Troubleshoot connection problems.

Connect and authenticate

Why does a connection that works with Driver 17 fail with a certificate error on Driver 18?

Driver 18 defaults to Encrypt=yes. Driver 17 defaults to Encrypt=no only when no nonempty Authentication setting or access token is supplied. A nonempty Authentication setting, including Authentication=SqlPassword, or an access token changes the Driver 17 default to Encrypt=yes. Explicit encryption settings override these defaults.

Check the effective settings in your connection string, DSN, and preconnection attributes set through SQLSetConnectAttr. For example, Encrypt=yes in a DSN or SQL_COPT_SS_ENCRYPT=SQL_EN_ON requests encryption even when the connection string omits Encrypt. Supply access tokens only through the SQL_COPT_SS_ACCESS_TOKEN connection attribute, not a connection-string keyword.

With Encrypt=yes and TrustServerCertificate=no, both drivers encrypt the connection and validate the server certificate. With Encrypt=no, Driver 17 doesn't validate the certificate, while Driver 18 validates it if the server forces encryption and TrustServerCertificate=no. A connection that previously used the Driver 17 Encrypt=no default can therefore fail with Driver 18 against a server with a self-signed or otherwise untrusted certificate. With a self-signed certificate, the Driver 18 error looks like this:

[Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:0A000086:SSL routines::certificate verify failed:self-signed certificate]
[Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection. For solutions related to encryption errors, see https://go.microsoft.com/fwlink/?linkid=2226722

Prefer a trusted certificate or certificate pinning. Use these options:

  • Install a certificate on the server that's issued by a certificate authority the client trusts. If the certificate is trusted but its name doesn't match the Server value, set HostNameInCertificate to the name in the certificate. HostNameInCertificate changes only the expected name, so it doesn't fix a self-signed certificate.
  • With Driver 18.1 and later versions and a server that supports Tabular Data Stream (TDS) 8.0, set Encrypt=strict and set ServerCertificate to the path of a copy of the server's certificate. The driver then accepts only that exact certificate. ServerCertificate works only in strict mode.
  • Set Encrypt=no only if you accept unencrypted application traffic when the server doesn't force encryption. This matches the Driver 17 default only when no nonempty Authentication setting or access token is supplied and no encryption override is set. If the server forces encryption, Driver 18 still validates the certificate unless TrustServerCertificate=yes disables validation.

Caution

TrustServerCertificate=yes doesn't enable encryption. With Encrypt=yes, it bypasses certificate validation while keeping traffic encrypted, leaving the connection open to adversary-in-the-middle attacks. With Encrypt=no, application traffic remains unencrypted unless the server forces encryption; if the server forces encryption, certificate validation is bypassed. With Encrypt=strict, the driver ignores TrustServerCertificate and validates the certificate, or matches it against ServerCertificate when configured. Prefer a trusted certificate or certificate pinning.

For more information, see Default encryption behavior.

Does the driver support Kerberos authentication?

Yes. Get a Kerberos ticket with kinit, then connect with Trusted_Connection=yes in the connection string or DSN. The SQL Server instance needs a registered service principal name (SPN). For setup steps, see Use integrated authentication.

Does the driver support Microsoft Entra ID authentication?

Yes, for Azure SQL Database, Azure SQL Managed Instance, and SQL Server 2022 and later versions. To set up SQL Server, including through Azure Arc, use Microsoft Entra authentication for SQL Server. On Linux and macOS, Driver 17 and later versions support these methods:

  • Managed identity, with Authentication=ActiveDirectoryMsi, starting with Driver 17.3.
  • Service principal, with Authentication=ActiveDirectoryServicePrincipal, starting with Driver 17.7.
  • Integrated authentication through Kerberos in a federated environment, with Authentication=ActiveDirectoryIntegrated, starting with Driver 17.6.
  • An access token that your application obtains, passed through the SQL_COPT_SS_ACCESS_TOKEN connection attribute.

ActiveDirectoryInteractive is available only in the Windows driver. ActiveDirectoryPassword is deprecated. Driver-managed authentication on Linux and macOS doesn't support scenarios that require conditional access policies. If your application acquires an access token separately, the authentication library and Microsoft Entra ID policies govern that token acquisition. Pass the token through SQL_COPT_SS_ACCESS_TOKEN.

On Alpine Linux, integrated authentication requires a libcurl build with support for the Simple and Protected Generic Security Service Application Program Interface Negotiation Mechanism (SPNEGO). Check your installed libcurl capabilities rather than assuming the default package supports it.

For connection strings and code samples, see Use Microsoft Entra ID with the ODBC driver.

Develop and troubleshoot

Can an existing ODBC application use the driver on Linux or macOS?

Yes. An application written to the ODBC application programming interface (API) and built against unixODBC can load this driver. To use SQL Server-specific features, include msodbcsql.h after the unixODBC headers. For compiler commands and library names, see Develop C and C++ applications with the ODBC driver.

Is there a sample application?

Yes. Connect and query with C++ and ODBC builds and runs a sample on Linux, macOS, and Windows.

How do I trace ODBC calls?

Trace files can contain sensitive data. As the account that runs your application, create a directory that only that account can access:

mkdir -m 700 "$HOME/odbc-trace"

Add these settings to the [ODBC] section of odbcinst.ini. Replace /home/<user>/odbc-trace/odbctrace.log with the absolute path inside the directory you created. On macOS, home directories typically use /Users/<user> instead of /home/<user>.

Keep the full trace-file path to 62 bytes or fewer to avoid truncation by unixODBC.

[ODBC]
Trace = Yes
TraceFile = /home/<user>/odbc-trace/odbctrace.log

These settings enable tracing for applications that use this driver manager configuration, and tracing slows them down. Use a separate private directory for each application account. Remove Trace = Yes when you finish, and delete trace files you no longer need. For per-application tracing, see Data access tracing on Linux and macOS.

Character data

Which Unicode encoding should an application use?

Use UTF-16LE (little endian) for SQLWCHAR data. Use UTF-16 SQLWCHAR buffers with the ODBC wide-character APIs instead of the native wchar_t type, which is 32 bits on Linux and macOS.

Use UTF-8 for SQLCHAR data. Starting with Driver 17, the driver also accepts a set of single-byte and double-byte code pages for SQLCHAR data when the process locale selects one. Processes start in the C locale, so the driver uses UTF-8 unless the application calls setlocale. For the list of encodings, see Handle character data.