JDBC Connection for offset storage validation issues
- Dominant language
- HTML
- Stars
- 6
- Forks
- 8
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 1
Description
## Bug report
**What Debezium connector do you use and what version?**
Debezium Server 3.5. The main source uses the SQL Server connector, but the issue is with the JDBC connector for offset storage.
---
**What is the connector configuration?**
```
# Source database config
connector.class=io.debezium.connector.sqlserver.SqlServerConnector
database.hostname=.database.windows.net
database.port=1433
database.user=testlogin
database.password=
database.names=
database.server.name=
table.include.list=
snapshot.mode=initial
# Offset storage
offset.storage=io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore
offset.flush.interval.ms=10000
# JDBC offset storage
offset.storage.jdbc.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI
offset.storage.jdbc.table.name=dbo.debezium_offset_storage
offset.storage.jdbc.table.ddl=CREATE TABLE dbo.debezium_offset_storage (
id VARCHAR(36) NOT NULL,
offset_key VARCHAR(1255),
offset_val VARCHAR(1255),
record_insert_ts DATETIME2 NOT NULL,
record_insert_seq INTEGER NOT NULL,
PRIMARY KEY (id)
)
# Schema history
schema.history.internal=io.debezium.storage.jdbc.history.JdbcSchemaHistory
schema.history.internal.jdbc.connection.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI
schema.history.internal.jdbc.table.name=dbo.debezium_database_history
schema.history.internal.jdbc.table.ddl=CREATE TABLE dbo.debezium_database_history (
id VARCHAR(36) NOT NULL,
history_data VARCHAR(MAX),
history_data_seq INTEGER,
record_insert_ts DATETIME2 NOT NULL,
record_insert_seq INTEGER NOT NULL,
PRIMARY KEY (id)
)
# Sink config
sink.type=kafka
sink.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093
sink.kafka.producer.security.protocol=SASL_SSL
sink.kafka.producer.sasl.mechanism=PLAIN
sink.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer
sink.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer
sink.kafka.producer.sasl.jaas.config=
```
---
**What is the captured database version and mode of deployment?**
_E.g. on-premises, with a specific cloud provider, etc._
```
Source database: Microsoft SQL Server on Azure SQL Database
Offset/schema history database: Azure SQL Database
Deployment mode: Debezium Server running in Azure Container Apps
Authentication method for JDBC offset/schema history storage: ActiveDirectoryMSI (Managed Identity) using Microsoft SQL Server JDBC driver
```
---
**What behavior do you expect?**
```
Debezium JDBC offset storage and JDBC schema history storage should support Azure SQL Managed Identity authentication using a JDBC URL such as:
jdbc:sqlserver://:1433;databaseName=;encrypt=true;authentication=ActiveDirectoryMSI
without requiring jdbc.user/jdbc.password configuration properties.
Alternatively, if the properties are mandatory for validation purposes, empty values should be accepted and should not be forwarded to the JDBC driver.
```
---
**What behavior do you see?**
```
Debezium validates the JDBC offset storage configuration and requires offset.storage.jdbc.password to be present.
If the property is omitted, Debezium fails validation with:
Validation error for property with prefix 'offset.storage.':
The 'jdbc.password' value is invalid: A value is required
If a password value is supplied to satisfy validation, the Microsoft SQL Server JDBC driver rejects the connection because Managed Identity authentication does not allow password usage:
Cannot use "Authentication=ActiveDirectoryManagedIdentity"
with "Password" connection string keyword.
This creates a configuration deadlock where:
- Debezium requires the password property
- The JDBC driver forbids the password property
making Azure Managed Identity authentication unusable for JdbcOffsetBackingStore and JdbcSchemaHistory.
```
---
**Do you see the same behaviour using the latest released Debezium version?**
_Ideally, also verify with the latest Alpha/Beta/CR version._
`Is see it in 3.5, haven't verified it with 3.6 but none of the release notes mention anything similar`
---
**Do you have the connector logs, ideally from start till finish?**
_You might be asked later to provide [DEBUG/TRACE](https://debezium.io/documentation/reference/stable/operations/logging.html) level log._
This is the relevant part of the logs
```
2026-05-19T07:54:32.7078043Z stdout F {"timestamp":"2026-05-19T07:54:32.70701015Z","sequence":593,"loggerClassName":"org.slf4j.impl.Slf4jLogger","loggerName":"io.debezium.server.ConnectorLifecycle","level":"ERROR","message":"Connector completed: success = 'false', message = 'Failed to connect JDBC offset backing store: {connector.class=io.debezium.connector.sqlserver.SqlServerConnector, schema.history.internal.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, record.processing.shutdown.timeout.ms=1000, schema.history.internal.kafka.producer.security.protocol=SASL_SSL, offset.storage.jdbc.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, schema.history.internal.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, record.processing.order=ORDERED, topic.prefix=hix, offset.storage.file.filename=, schema.history.internal.jdbc.connection.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, offset.storage.kafka.producer.security.protocol=SASL_SSL, record.processing.threads=, errors.retry.delay.initial.ms=300, schema.history.internal.jdbc.table.ddl=CREATE TABLE dbo.debezium_database_history (id VARCHAR(36) NOT NULL, history_data VARCHAR(MAX), history_data_seq INTEGER, record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), value.converter=org.apache.kafka.connect.json.JsonConverter, offset.storage.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, key.converter=org.apache.kafka.connect.json.JsonConverter, schema.history.internal.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, schema.history.internal.kafka.producer.sasl.mechanism=PLAIN, database.user=testlogin, offset.storage.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, database.names=, offset.storage=io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore, schema.history.internal.jdbc.table.name=dbo.debezium_database_history, database.server.name=, offset.flush.timeout.ms=5000, errors.retry.delay.max.ms=10000, offset.storage.kafka.producer.sasl.mechanism=PLAIN, schema.history.internal.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, database.port=1433, offset.storage.jdbc.table.name=dbo.debezium_offset_storage, offset.flush.interval.ms=10000, offset.storage.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, internal.task.management.timeout.ms=40000, schema.history.internal=io.debezium.storage.jdbc.history.JdbcSchemaHistory, record.processing.with.serial.consumer=false, errors.max.retries=-1, database.hostname=sql-dpci-test-sql-nonprd-we.database.windows.net, database.password=, name=kafka, offset.storage.jdbc.table.ddl=CREATE TABLE dbo.debezium_offset_storage (id VARCHAR(36) NOT NULL, offset_key VARCHAR(1255), offset_val VARCHAR(1255), record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), table.include.list=dbo.AGENDA_AFSPCODE, offset.storage.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, snapshot.mode=initial}', error = 'java.lang.IllegalStateException: Failed to connect JDBC offset backing store: {connector.class=io.debezium.connector.sqlserver.SqlServerConnector, schema.history.internal.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, record.processing.shutdown.timeout.ms=1000, schema.history.internal.kafka.producer.security.protocol=SASL_SSL, offset.storage.jdbc.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, schema.history.internal.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, record.processing.order=ORDERED, topic.prefix=hix, offset.storage.file.filename=, schema.history.internal.jdbc.connection.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, offset.storage.kafka.producer.security.protocol=SASL_SSL, record.processing.threads=, errors.retry.delay.initial.ms=300, schema.history.internal.jdbc.table.ddl=CREATE TABLE dbo.debezium_database_history (id VARCHAR(36) NOT NULL, history_data VARCHAR(MAX), history_data_seq INTEGER, record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), value.converter=org.apache.kafka.connect.json.JsonConverter, offset.storage.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, key.converter=org.apache.kafka.connect.json.JsonConverter, schema.history.internal.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, schema.history.internal.kafka.producer.sasl.mechanism=PLAIN, database.user=testlogin, offset.storage.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, database.names=, offset.storage=io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore, schema.history.internal.jdbc.table.name=dbo.debezium_database_history, database.server.name=, offset.flush.timeout.ms=5000, errors.retry.delay.max.ms=10000, offset.storage.kafka.producer.sasl.mechanism=PLAIN, schema.history.internal.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, database.port=1433, offset.storage.jdbc.table.name=dbo.debezium_offset_storage, offset.flush.interval.ms=10000, offset.storage.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, internal.task.management.timeout.ms=40000, schema.history.internal=io.debezium.storage.jdbc.history.JdbcSchemaHistory, record.processing.with.serial.consumer=false, errors.max.retries=-1, database.hostname=sql-dpci-test-sql-nonprd-we.database.windows.net, database.password=, name=kafka, offset.storage.jdbc.table.ddl=CREATE TABLE dbo.debezium_offset_storage (id VARCHAR(36) NOT NULL, offset_key VARCHAR(1255), offset_val VARCHAR(1255), record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), table.include.list=dbo.AGENDA_AFSPCODE, offset.storage.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, snapshot.mode=initial}'","threadName":"pool-7-thread-1","threadId":30,"mdc":{},"ndc":"","hostName":"debezium-server--0000008-854bdb5779-wrt9z","processName":"/usr/lib/jvm/java-21-openjdk-21.0.11.0.10-1.el8.x86_64/bin/java","processId":1,"exception":{"refId":1,"exceptionType":"java.lang.IllegalStateException","message":"Failed to connect JDBC offset backing store: {connector.class=io.debezium.connector.sqlserver.SqlServerConnector, schema.history.internal.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, record.processing.shutdown.timeout.ms=1000, schema.history.internal.kafka.producer.security.protocol=SASL_SSL, offset.storage.jdbc.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, schema.history.internal.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, record.processing.order=ORDERED, topic.prefix=hix, offset.storage.file.filename=, schema.history.internal.jdbc.connection.url=jdbc:sqlserver://.database.windows.net:1433;databaseName=debezium-state;encrypt=true;authentication=ActiveDirectoryMSI, offset.storage.kafka.producer.security.protocol=SASL_SSL, record.processing.threads=, errors.retry.delay.initial.ms=300, schema.history.internal.jdbc.table.ddl=CREATE TABLE dbo.debezium_database_history (id VARCHAR(36) NOT NULL, history_data VARCHAR(MAX), history_data_seq INTEGER, record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), value.converter=org.apache.kafka.connect.json.JsonConverter, offset.storage.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, key.converter=org.apache.kafka.connect.json.JsonConverter, schema.history.internal.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, schema.history.internal.kafka.producer.sasl.mechanism=PLAIN, database.user=testlogin, offset.storage.kafka.producer.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=debezium-sender;SharedAccessKey=";, database.names=, offset.storage=io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore, schema.history.internal.jdbc.table.name=dbo.debezium_database_history, database.server.name=, offset.flush.timeout.ms=5000, errors.retry.delay.max.ms=10000, offset.storage.kafka.producer.sasl.mechanism=PLAIN, schema.history.internal.kafka.producer.value.serializer=org.apache.kafka.common.serialization.StringSerializer, database.port=1433, offset.storage.jdbc.table.name=dbo.debezium_offset_storage, offset.flush.interval.ms=10000, offset.storage.kafka.producer.bootstrap.servers=.servicebus.windows.net:9093, internal.task.management.timeout.ms=40000, schema.history.internal=io.debezium.storage.jdbc.history.JdbcSchemaHistory, record.processing.with.serial.consumer=false, errors.max.retries=-1, database.hostname=sql-dpci-test-sql-nonprd-we.database.windows.net, database.password=, name=kafka, offset.storage.jdbc.table.ddl=CREATE TABLE dbo.debezium_offset_storage (id VARCHAR(36) NOT NULL, offset_key VARCHAR(1255), offset_val VARCHAR(1255), record_insert_ts DATETIME2 NOT NULL, record_insert_seq INTEGER NOT NULL, PRIMARY KEY (id)), table.include.list=dbo.AGENDA_AFSPCODE, offset.storage.kafka.producer.key.serializer=org.apache.kafka.common.serialization.StringSerializer, snapshot.mode=initial}","frames":[{"class":"io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore","method":"configure","line":76},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"createAndStartOffsetStore","line":837},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"initializeConnector","line":375},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"run","line":208},{"class":"io.debezium.server.DebeziumServer","method":"lambda$start$0","line":166},{"class":"java.util.concurrent.ThreadPoolExecutor","method":"runWorker","line":1144},{"class":"java.util.concurrent.ThreadPoolExecutor$Worker","method":"run","line":642},{"class":"java.lang.Thread","method":"run","line":1583}],"causedBy":{"exception":{"refId":2,"exceptionType":"io.debezium.DebeziumException","message":"Error configuring an instance of 'JdbcOffsetBackingStoreConfig' with prefix 'offset.storage.'; check the logs for errors","frames":[{"class":"io.debezium.storage.jdbc.JdbcCommonConfig","method":"","line":70},{"class":"io.debezium.storage.jdbc.offset.JdbcOffsetBackingStoreConfig","method":"","line":83},{"class":"io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore","method":"configure","line":70},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"createAndStartOffsetStore","line":837},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"initializeConnector","line":375},{"class":"io.debezium.embedded.async.AsyncEmbeddedEngine","method":"run","line":208},{"class":"io.debezium.server.DebeziumServer","method":"lambda$start$0","line":166},{"class":"java.util.concurrent.ThreadPoolExecutor","method":"runWorker","line":1144},{"class":"java.util.concurrent.ThreadPoolExecutor$Worker","method":"run","line":642},{"class":"java.lang.Thread","method":"run","line":1583}]}}}}
```
---
**How to reproduce the issue using our [tutorial](https://github.com/debezium/debezium-examples/tree/main/tutorial) deployment?**
```
1. Deploy Debezium Server with JDBC offset storage and JDBC schema history enabled.
2. Configure Microsoft SQL Server JDBC URLs using Azure Managed Identity authentication:
offset.storage=io.debezium.storage.jdbc.offset.JdbcOffsetBackingStore
offset.storage.jdbc.url=jdbc:sqlserver://:1433;databaseName=;encrypt=true;authentication=ActiveDirectoryMSI
schema.history.internal=io.debezium.storage.jdbc.history.JdbcSchemaHistory
schema.history.internal.jdbc.connection.url=jdbc:sqlserver://:1433;databaseName=;encrypt=true;authentication=ActiveDirectoryMSI
3. Omit:
offset.storage.jdbc.password
because Managed Identity authentication does not use passwords.
4. Start Debezium Server.
5. Observe startup failure:
Validation error for property with prefix 'offset.storage.':
The 'jdbc.password' value is invalid: A value is required
6. Add a dummy password value:
offset.storage.jdbc.password=dummy
7. Restart Debezium Server.
8. Observe JDBC driver failure:
Cannot use "Authentication=ActiveDirectoryManagedIdentity"
with "Password" connection string keyword.
This reproduces the issue consistently.
The issue appears independent of Azure Container Apps specifically and should reproduce anywhere the Microsoft SQL Server JDBC driver is used with ActiveDirectoryMSI authentication.
```
Contributor guide
Assessment
This issue has not been assessed yet.