Problem:
A MySQL table named with embedded spaces (schema-qualified as “dbo.Sourcing Id Master”) could not be used in the Debezium connector’s message.key.columns setting. The connector configuration contained the entry “message.key.columns”: “dbo.Sourcing Id Master:id” and the connector validation rejected it with an invalid-format error referencing the expected pattern for message.key.columns. Attempts to escape characters in the message.key.columns value failed and the connector would not start because the configuration failed validation. The customer also asked whether spaces are allowed in table.include.list.
Process:
Step 1: Reproduce and capture the validation failure
Connector configuration and the validation response were examined to reproduce the symptom. The connector failed at config validation with an error indicating the message.key.columns value did not match the expected pattern for a fully qualified table/column mapping. This established that the problem was a configuration-time validation failure before the connector reached binlog capture.
Step 2: Test suggested escaping variants from the client
The two escaping variants provided by the customer were applied to the connector configuration (backslash-escaped dot and backslash-escaped spaces) and the connector was revalidated. Both variants produced the same validation failure. This showed the problem persisted despite common escaping attempts and narrowed the issue to how the configuration validator parses that property, not to runtime discovery of the table.
Step 3: Inspect the message.key.columns validation rules
Connector plugin validation rules and documentation were reviewed to determine the accepted format for message.key.columns. The pattern used by the validator requires the left-hand fully-qualified identifier portion to be non-whitespace (no spaces) before the colon. This confirmed that the property’s validator disallows whitespace in the schema.table segment, so escaping spaces in that field cannot satisfy the validator. That discovery was critical because it eliminated further attempts at escaping as a viable path.
Step 4: Verify table discovery and alternate capture pathways
Connector discovery behavior and the table.include.list semantics were examined. The table.include.list accepts a regular expression and can match literal spaces in the table portion (for discovery), so it was possible for Debezium to capture binlog events for the table even if message.key.columns could not be set for that same literal name. Logs and information_schema checks were used to confirm the MySQL table exists and is present in binlog events, showing capture was feasible if the connector started.
Step 5: Choose a practical workaround that avoids the validator limitation
Because message.key.columns validator rejects whitespace in the fully-qualified name, an alternative that did not rely on that property was selected. The connector was reconfigured to include the target table via table.include.list (using an escaped dot for the schema separator and literal space in the table portion) and the message.key.columns entry was removed. A Kafka Connect single-message transform (SMT) of type ValueToKey was added to extract the primary-key field (id) from the record value and set it as the Kafka message key. The connector was restarted and validation succeeded (no message.key.columns entry to validate); runtime records were observed with keys constructed by the SMT, and the table was being captured as expected.
Solution:
Debezium was configured to capture the table using table.include.list while avoiding the message.key.columns validator that disallows whitespace in the fully qualified identifier. The connector configuration removed the message.key.columns mapping and added an SMT to build the Kafka record key from the captured value fields, for example:
transforms=ValueToKey
transforms.ValueToKey.type=org.apache.kafka.connect.transforms.ValueToKey
transforms.ValueToKey.fields=id
This uses Debezium for data capture and Kafka Connect SMTs to construct the message key at runtime instead of relying on the message.key.columns parser. Architecturally this works because Debezium still produces the primary-key fields in the record value, and the SMT operates on the record payload without triggering the connector’s configuration-time validator.
Conclusion:
Connector validation errors were eliminated and the table with spaces was successfully captured. Kafka records now contain keys derived from the id column via an SMT, restoring expected downstream partitioning and consumer key semantics. The chosen approach removes the need to rename source objects or change database schema while avoiding configuration-validation constraints, reducing operational risk and enabling stable CDC processing.