Kafka is fundamentally about writing and reading byte arrays, but in practice the layer that converts those bytes into formats humans and downstream systems can work with is critical. That layer is the client Serializer/Deserializer and the Kafka Connect Converter.
This article focuses on Connect's key.converter and value.converter: how to choose them, how to integrate with Schema Registry, and how to avoid common pitfalls. We also clarify the distinctions CCDAK tends to test.
Kafka clients (Producer/Consumer) use Serializers and Deserializers to convert in-app objects to and from byte arrays. Kafka Connect, on the other hand, uses Converters (key.converter / value.converter) to handle data and schemas at the boundary between a connector and Kafka.
They differ in implementation, where they are configured, and how schema-aware they are. A Converter translates between Connect's internal data model (Schema + Struct, etc.) and the bytes on Kafka, and integrates cleanly with SMTs (Single Message Transforms), retries, and error handling.
| Target | Layer | Typical classes / config example |
|---|---|---|
| Converter (Connect) | Kafka Connect connector boundary | org.apache.kafka.connect.storage.StringConverter / io.confluent.connect.avro.AvroConverter (key.converter, value.converter) |
| Serializer/Deserializer (client) | Producer/Consumer application boundary | org.apache.kafka.common.serialization.StringSerializer / StringDeserializer (key.serializer, value.deserializer) |
| SerDe (Streams) | Kafka Streams (paired with types) | org.apache.kafka.common.serialization.Serdes.String() (passed to the builder) |
Where conversion happens in Kafka (app vs Connect)
Serializer vs Converter configuration snippets, side by side
# Producer (application side)
bootstrap.servers=broker:9092
key.serializer=org.apache.kafka.common.serialization.StringSerializer
value.serializer=org.apache.kafka.common.serialization.ByteArraySerializer
# Consumer (application side)
bootstrap.servers=broker:9092
key.deserializer=org.apache.kafka.common.serialization.StringDeserializer
value.deserializer=org.apache.kafka.common.serialization.ByteArrayDeserializer
auto.offset.reset=earliest
# Kafka Connect (worker / global defaults)
key.converter=org.apache.kafka.connect.storage.StringConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
value.converter.schemas.enable=true
# (When using Schema Registry)
# key.converter=io.confluent.connect.avro.AvroConverter
# value.converter=io.confluent.connect.avro.AvroConverter
# key.converter.schema.registry.url=http://schema-registry:8081
# value.converter.schema.registry.url=http://schema-registry:8081Kafka records hold key and value separately, and Connect configures key.converter and value.converter independently. This matters in practice. Partitioning typically hashes the key bytes, so keeping the key representation stable directly affects data placement across the cluster and how records are grouped.
Values, in contrast, tend to undergo schema evolution, so teams typically pick Avro, Protobuf, or JSON Schema together with Schema Registry. A simple String/Long key paired with an Avro/Protobuf value is a classic real-world combination.
Per-connector override (overrides the worker default)
{
"name": "jdbc-source-custom",
"config": {
"connector.class": "io.confluent.connect.jdbc.JdbcSourceConnector",
"tasks.max": "1",
"connection.url": "jdbc:postgresql://db:5432/app",
"mode": "incrementing",
"incrementing.column.name": "id",
"topic.prefix": "db_",
"key.converter": "org.apache.kafka.connect.storage.StringConverter",
"value.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter.schema.registry.url": "http://schema-registry:8081"
}
}Confluent's AvroConverter, ProtobufConverter, and JsonSchemaConverter integrate with Schema Registry and serialize Connect's internal data (Schema + Value) per record with the appropriate schema ID. Downstream consumers can then safely reconstruct the data with the matching deserializer, such as KafkaAvroDeserializer.
JsonConverter does not depend on Schema Registry, but when schemas.enable=true the JSON on Kafka contains schema information, which improves interoperability between Connect deployments. Ordinary consumers handling that JSON directly need to understand its structure.
Minimal consumer configuration for Avro
bootstrap.servers=broker:9092
group.id=orders-app
key.deserializer=org.apache.kafka.common.serialization.StringDeserializer
value.deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
schema.registry.url=http://schema-registry:8081
auto.offset.reset=earliestChoose a format based on observability, interoperability, schema evolution, and performance. The cost of migrating later, while the system is live, also matters.
Below are policies frequently adopted in the field.
Small pipeline example (keys as String, values migrating to JSON Schema)
# Worker defaults
key.converter=org.apache.kafka.connect.storage.StringConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
value.converter.schemas.enable=true
# Later, migrate only the connector for the target topic to JSON Schema
value.converter=io.confluent.connect.json.JsonSchemaConverter
value.converter.schema.registry.url=http://schema-registry:8081Format mismatches and missing schema configuration are the classic culprits. Inspect the bytes safely and check both the Converter side and the Serializer side.
Record keys directly affect partitioning and downstream logic. Changing the key representation changes its hash, so old and new data may end up on different partitions — be careful.
Inspecting messages with kcat (String key, Avro value)
# Keys as strings, values decoded as Avro
kcat -b broker:9092 -t orders -C -K: -f 'key=%k\tval=%s\n' \
-s key=string -s value=avro -r http://schema-registry:8081The exam frequently tests layer distinctions — which setting goes where. Picture the system diagram and quickly identify which boundary a given action happens at.
CCDAK
問題 1
On a Kafka Connect Source Connector, you want to write string keys and schema-managed values to Kafka. Which combination of settings is appropriate?
正解: A
Connect uses Converters. Use StringConverter for the key and an Avro/Protobuf/JSON Schema converter for the value, and supply schema.registry.url on the converter for formats that use Schema Registry. Serializers are a client (application) concept and cannot substitute for Connect's Converters. JSON with schemas.enable=false provides no guarantee of schema evolution.
Do key.converter and value.converter have to be the same class?
No. Typically the key uses StringConverter or LongConverter while the value uses an Avro/Protobuf/JSON Schema converter. Pick them independently based on your requirements.
What is the difference between schemas.enable=true and false in JsonConverter?
true emits JSON with an embedded schema (good for Connect-to-Connect interop and SMTs), while false emits plain JSON without a schema. The latter is easier for ordinary consumers to handle directly, but the application has to manage type information and schema evolution itself.
Where do I configure Schema Registry compatibility?
Set the compatibility level (such as BACKWARD) on the Schema Registry server, either per subject or globally. Converters and serializers honor that setting when registering and validating schemas.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Kafka Topics & Partitions: Distribution Fundamentals (2026)
How Kafka topics and partitions enable scale — ordering guar...
CCDAK Exam Guide: Confluent Certified Developer (2026)
Complete prep for the CCDAK exam — Producer/Consumer API, St...
CCAAK Exam Guide: Confluent Certified Administrator (2026)
Pass the CCAAK exam — cluster management, partitions, securi...
Kafka Replicas & ISR: Fault Tolerance Explained (2026)
Replica placement, in-sync replicas (ISR), leader election. ...
Kafka Offsets: Commit Modes & Consumer Position (2026)
Offset semantics — auto vs. manual commit, __consumer_offset...