2025, Dec 24 23:00

Connect to Microsoft SQL Server from Linux via JDBC using Kerberos (fix DLL integrated auth errors)

Fix SQL Server JDBC auth on Linux: avoid Windows DLL errors by using Kerberos. Set integratedSecurity=true and authenticationScheme=Javakerberos. Have kinit.

Connecting from Linux to Microsoft SQL Server with “Windows integrated security” via the Microsoft JDBC driver often fails with an authentication DLL error. The root of the issue is that native integrated auth is Windows-only, and the driver’s default behavior attempts to load a Windows .DLL, which cannot work on Linux. The fix is to choose the correct authentication scheme and configure the connection string accordingly.

Problem in context

The environment has a valid Kerberos ticket created via kinit, and the connection is attempted from PySpark using the Microsoft JDBC driver. The runtime produces messages like “This driver is not configured for integrated authentication” and “Unable to load authentication DLL mssql-jdbc_auth-12.10.0.x64”. The code below reproduces the situation and mirrors the program logic that leads to the error.

from pyspark.sql import SparkSession
jar_file = "./sqljdbc_12.10/enu/jars/mssql-jdbc-12.10.0. jre8.jar"
native_folder = "./sqljdbc_12.10/enu/auth/x64/"
native_file = "./sqljdbc_12.10/enu/auth/x64/mssql-jdbc_auth-12.10.0.x64.dll"
sess = SparkSession.builder \
    .appName("SQLServerKerberos") \
    .config("spark.driver.extraClassPath", jar_file) \
    .config("spark.executor.extraClassPath", jar_file) \
    .config("spark.executor. extraJavaOptions", f"-Djava.library. path={native_folder}") \
    .config("spark.driver.extraJavaOptions", f"-Djava.library.path={native_folder}") \
    .getOrCreate()
pno = 1433
dbn = "dbname"
krb_principal = "uname@domain"
host = "server.domain"
conn_url = f"jdbc:sqlserver://{host}: {pno};" \
           + f"databaseName={dbn};" \
           + "Encrypt=false;" \
           + "Trusted_Connection=true;" \
           + "TrustServerCertificate=true;" \
           + "ServerSPN=RestrictedKrbHost/RSP-HR-DB3;" \
           + "AuthScheme=JavaKerberos;" \
           + "integratedSecurity=true;" \
           + f"principal={krb_principal}"
opts = {
    "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}
frame = sess.read.jdbc(url=conn_url, table="person", properties=opts)
frame.show()
sess.stop()

It is then executed similarly to:

spark-submit -- driver-class-path "./sqljdbc_12.10/enu/jars/mssql-jdbc-12.10.0. jre8.jar" -- jars "./sqljdbc_12.10/enu/jars/mssql-jdbc-12.10.0. jre8.jar" --driver-library-path "./sqljdbc_12.10/enu/auth/x64/" src/extra.py

com.microsoft.sqlserver.jdbc.SQLServerException: This driver is not configured for integrated authentication

java.lang.UnsatisfiedLinkError: Unable to load authentication DLL mssql-jdbc_auth-12.10.0.x64

What actually goes wrong

The Microsoft JDBC driver for SQL Server supports multiple ways to perform what is typically called “Windows” authentication. On Linux, native Windows integrated security relies on a .DLL and only works on Windows. The driver defaults to native integrated auth, so unless you explicitly choose a different scheme, it tries to load the Windows DLL and fails on Linux. Additionally, abbreviating the property name to AuthScheme instead of using authenticationScheme means the driver doesn’t receive the intended setting and falls back to its default, which is again native authentication on Windows.

Supported authentication schemes in the JDBC driver

Kerberos works cross-platform using the JVM’s built-in mechanisms. To use it, set integratedSecurity=true and authenticationScheme=Javakerberos in the connection string, and ensure a TGT exists by running kinit. Do not shorten authenticationScheme to authScheme.

Windows integrated security is native and uses a .DLL. It only works on Windows when you specify integratedSecurity=true and authenticationScheme=NativeAuthentication.

NTLM can be used by setting integratedSecurity=true and authenticationScheme=NTLM and providing Windows credentials as userName and password in the connection string. It mostly works but is not recommended; Kerberos is the preferred approach.

authenticationScheme=NativeAuthentication is the default; if you omit or mis-specify the property, you get the familiar “driver is not configured...” error because the driver attempts the Windows-only path.

Reference: Microsoft JDBC driver connection properties.

The fix on Linux: force Java Kerberos

The resolution is to explicitly use Kerberos via the driver’s Java-based flow. Keep integratedSecurity=true and set authenticationScheme=Javakerberos. Do not point java.library.path to the Windows auth .DLL, and do not abbreviate the property name. Ensure you have a valid ticket with kinit before launching the job.

from pyspark.sql import SparkSession
jdbc_jar = "./sqljdbc_12.10/enu/jars/mssql-jdbc-12.10.0. jre8.jar"
spark_ctx = SparkSession.builder \
    .appName("SQLServerKerberosFixed") \
    .config("spark.driver.extraClassPath", jdbc_jar) \
    .config("spark.executor.extraClassPath", jdbc_jar) \
    .getOrCreate()
sql_port = 1433
sql_db = "dbname"
user_principal = "uname@domain"
sql_host = "server.domain"
jdbc_conn = f"jdbc:sqlserver://{sql_host}: {sql_port};" \
           + f"databaseName={sql_db};" \
           + "Encrypt=false;" \
           + "Trusted_Connection=true;" \
           + "TrustServerCertificate=true;" \
           + "ServerSPN=RestrictedKrbHost/RSP-HR-DB3;" \
           + "authenticationScheme=Javakerberos;" \
           + "integratedSecurity=true;" \
           + f"principal={user_principal}"
jdbc_opts = {
    "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}
result_df = spark_ctx.read.jdbc(url=jdbc_conn, table="person", properties=jdbc_opts)
result_df.show()
spark_ctx.stop()

Why this matters

Choosing the wrong authentication scheme silently pushes the driver to its default behavior, which assumes Windows-native integrated auth, triggers a native .DLL load, and fails with confusing errors on Linux. Being explicit about authenticationScheme avoids needless troubleshooting and keeps the security model aligned with the platform. When you are on Linux and need “Windows-like” SSO, Kerberos via the Java stack is the supported path.

Takeaways

On Linux, do not attempt native Windows integrated security with the JDBC driver; the .DLL is Windows-only. Use Kerberos by setting integratedSecurity=true and authenticationScheme=Javakerberos, and ensure a valid Kerberos ticket with kinit before running your job. Avoid abbreviations like AuthScheme; authenticationScheme must be spelled out or the driver falls back to NativeAuthentication and fails. NTLM exists but is not recommended; Kerberos is the sensible default for domain-based authentication from Linux.