# Confluent Schema Registry: versioned schemas, compatibility rules, REST

> A Java service that stores Avro, JSON Schema and Protobuf schemas behind a REST interface, enforces compatibility on write, and hands serializers to Kafka clients.

**confluentinc/schema-registry** — Confluent Schema Registry for Kafka

- Repository: https://github.com/confluentinc/schema-registry
- Website: https://docs.confluent.io/current/schema-registry/docs/index.html
- Stars: 2,465 · Forks: 1,162
- Language: Java
- License: NOASSERTION
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/confluentinc-schema-registry

## A serving layer for metadata, not a broker plugin

The README's first paragraph is the whole pitch: Schema Registry provides a serving layer for your metadata, with a RESTful interface for storing and retrieving Avro, JSON Schema and Protobuf schemas. It stores a versioned history of all schemas based on a specified subject name strategy, provides multiple compatibility settings, and allows evolution of schemas according to those settings.

The part that matters is the last clause about serializers. The registry ships serializers that plug into Apache Kafka clients and handle schema storage and retrieval for messages sent in any supported format. That is the difference between a schema store you call out of band and one that is on the hot path of every produce and consume. A message on the wire carries a schema id, the client resolves that id back to a schema, and the reader gets a typed object rather than a string to guess at.

Three properties make this workable in a Kafka setting. Subjects partition the namespace, versions accumulate under each subject, and each distinct schema gets a globally unique id. Compatibility rules then apply per subject or globally, so one team can run BACKWARD while another runs NONE on the same registry.

The scale of the codebase is worth registering too. The repository has around 2,400 stars and 1,100 forks, 394 open issues, no published releases on the repository itself, and a last push on 2026-09-28. Its default branch is still `master`, which is a small sign of its age and of how Confluent manages branches. Versioning travels with the Confluent Platform downloads instead.

## The REST surface, one curl per operation

The README's quickstart assumes Kafka and a Schema Registry running on default settings, and then walks the API in a sensible order: register, list, read, delete, check compatibility, read and write config. The read paths are short enough to see the shape of the resource model immediately.

```bash
curl -X GET http://localhost:8081/subjects
curl -X GET http://localhost:8081/subjects/Kafka-value/versions
curl -X GET http://localhost:8081/schemas/ids/1
curl -X GET http://localhost:8081/subjects/Kafka-value/versions/latest
curl -X DELETE http://localhost:8081/subjects/Kafka-value/versions/3
```

Two URL shapes carry the design. A schema is addressable two ways: by globally unique id under `/schemas/ids/1`, which is what a consumer holding a wire reference uses, and by subject and version under `/subjects/Kafka-value/versions/1`, which is what a producer or an operator uses. The response bodies make the same split visible, with the id lookup returning just the schema string and the subject lookup returning subject, version, id and schema together.

Writes use a content type of `application/vnd.schemaregistry.v1+json`, and configuration is both readable and writable at the top level and per subject:

```bash
curl -X GET http://localhost:8081/config
curl -X PUT http://localhost:8081/config/Kafka-value
```

The quickstart returns `{"compatibilityLevel":"BACKWARD"}` from the config read and shows the same value being written back for a single subject. Note that the two endpoints use different key names, `compatibilityLevel` on read and `compatibility` on write. Small inconsistency, worth knowing before you write a client against it.

## Compatibility checked before registration, not after

The compatibility endpoint takes a schema and a target version and answers whether it would be accepted, without storing anything. In the README that is expressed against the latest version of a subject under `/compatibility/subjects/Kafka-value/versions/latest`, returning `{"is_compatible":true}`.

This dry-run shape is the practical answer to the most common complaint about schema registries, which is that you only find out a schema is incompatible when a deploy fails. Being able to ask the question in CI, before anything is registered, is worth more than the elegance of the check itself.

The compatibility levels themselves are standard Confluent vocabulary: NONE accepts anything, BACKWARD means a new schema can read data written by the previous one, and there are forward and full variants with the same shape. The README does not enumerate them or explain them, which is the clearest boundary in this document. The configuration API lets you set the level globally and then override per subject, and the REST reference at docs.confluent.io is where the semantics are actually defined.

One thing to be careful about: the quickstart's compatibility check is scoped to the latest version. Checking against a specific historical version is a separate path, and the README does not show it.

## Repository layout: one module per schema type, plus encryption

The tree is where the breadth of this project shows, and it is a useful map if you are trying to work out which jar you actually need. Schema type support is split into parallel sets of modules: `avro-converter/`, `avro-data/`, `avro-serde/`, `avro-serializer/` and `avro-types/` on one side, matching `protobuf-converter/`, `protobuf-provider/`, `protobuf-serde/`, `protobuf-serializer/` and `protobuf-types/` on the other, and a third set for JSON Schema covering `json-schema-converter/`, `json-schema-provider/`, `json-schema-serde/`, `json-schema-serializer/` and the plain `json-serializer/`.

Shared abstractions sit in `client/`, `core/`, `schema-converter/`, `schema-serializer/` and `schema-types/`. Two directories are less predictable and more interesting. `schema-rules/` is the data quality and validation layer, which is the feature that turns a schema store into a governance point: rules can reject or transform records at serialization time. `logical-types/` handles the mapping between logical types and underlying representations.

Then there is the encryption half. `dek-registry/` and `dek-registry-client/` implement a Data Encryption Key registry, and there are six `client-encryption-*` modules: one per cloud, for AWS, Azure, GCP and Alicloud, one for HashiCorp Vault, and one for Google Tink. If your schemas contain sensitive fields, this is where envelope encryption with a key registry is implemented, and it is a materially different deployment conversation from plain schema storage.

Two more modules suggest how much of a platform this has become: `kafka-connect-schema-backup-api/` and `kafka-connect-schema-backup-core/` provide a Kafka Connect sink for backing schemas up, and `maven-plugin/` exists to embed schema registry lookups at build time. The `benchmark/` directory and the `jacoco-aggregate-schema-registry/` coverage module point to a project that takes performance and test coverage seriously.

## Building from source and starting it locally

Prebuilt binaries arrive as part of the Confluent Platform downloads, which is how most people run it. To install from source the README sends you to the Development section, which has a prerequisite that is easy to miss: development versions of `common` and `rest-utils` from Confluent's own repositories may be needed first. After that it is Maven.

```bash
mvn compile
mvn test
+mvn package [-DskipTests]
```

Running an instance against a local Kafka cluster using the configuration that ships with Kafka is a single exec invocation, pointed at the properties file in `config/`:

```bash
+mvn exec:java -pl :kafka-schema-registry -Dexec.args="config/schema-registry.properties"
+```

Packaging produces two artifacts in separate modules: the registry itself under `package-schema-registry/target/`, and a set of serde tools for Avro, JSON and Protobuf under `package-kafka-serde-tools/target/`. Those serde tools are the ones you use to inspect and convert schemas from the command line, which is more convenient than parsing the REST responses by hand when you are debugging a compatibility problem.

For actually running the service, the README recommends wrapper scripts rather than invoking Java directly: `bin/schema-registry-start` and `bin/schema-registry-stop`. Both appear in the tree's `bin/` directory. The REST interface has a built-in Jetty server, so there is no separate servlet container to configure.

## What the README leaves to the documentation

The README is a good API tour and a poor operations manual, and it is upfront about it. Its Documentation section links out to installing and configuring the registry, the schema management overview, a tutorial, the API reference, the page on serializers and deserializers for each supported schema type, the Kafka clients documentation and the Confluent Cloud quickstart.

Everything you need in order to decide whether to run this is in those links rather than in the repository. High availability and clustering, authentication and authorization, choosing a storage backend, subject name strategies in detail, the full compatibility level semantics, the serde tools' command line, and how to configure the client serializers to talk to your registry. The repository gives you the vocabulary and the endpoints; the documentation gives you the decisions.

Licensing is the other thing this README does not state plainly. The tree carries `LICENSE`, `LICENSE-Apache`, `LICENSE-ConfluentCommunity`, a `licenses/` directory, a `notices/` directory, a `generate-licenses-readme.txt` and a rendered `licenses-and-notices.html`, which is what a project mixing community and vendor components looks like. The repository metadata asserts no single license, so if you are considering it for a product with a compliance review, that is a question to answer against the files rather than assume from the ecosystem's reputation.

For getting help, the README points at documentation, a Zulip chat, a Bluesky account, the main issue tracker, and a separate tracker for installer and package issues. That split between the service and its packaging is a useful signal about where problems actually surface in this project.

## Conclusion

The design decision worth taking away is that compatibility is enforced at registration time rather than discovered by a consumer at read time, which converts an unbounded debugging problem into a write that either succeeds or fails with a reason. The REST API is small enough to read in one sitting and the versioned subject model maps directly onto how Kafka topics are already named, which is why the curl examples in the README double as the documentation. What the repository does not settle is the production side: HA deployment, authentication, storage backend choice and the client-side serializer configuration all live in the Confluent documentation rather than here. Start by running one locally with `config/schema-registry.properties`, register two versions of a subject, and set compatibility to BACKWARD before you write any client code.

## FAQ

### What is a schema registry?

It is a serving layer for schema metadata, and this one is a RESTful service that stores and retrieves Avro, JSON Schema and Protobuf schemas with a versioned history per subject. It also supplies serializers that plug into Kafka clients, so schema storage and retrieval happen as part of producing and consuming messages.

### Is a schema registry required for Kafka?

No. Kafka itself carries bytes and knows nothing about their structure. A registry becomes relevant when you want consumers to receive typed records instead of raw bytes, and when you want the schema to travel with the message so an old consumer can still read new data.

### Why use Avro instead of JSON?

That is a schema design trade-off rather than a registry feature, and the README does not take a position on it. What the registry adds is versioning and compatibility checking on top of whichever type you pick, including a compatibility endpoint that answers whether a candidate schema would be accepted before you register it.

### What are the three types of schema?

Avro, JSON Schema and Protobuf. Each has its own set of modules in the repository: converter, provider or data, serde, serializer and types directories, with the shared abstractions in `schema-converter/`, `schema-serializer/` and `schema-types/`.

## Sources

- [confluentinc/schema-registry on GitHub](https://github.com/confluentinc/schema-registry)
- [Issues](https://github.com/confluentinc/schema-registry/issues)
- [Project website](https://docs.confluent.io/current/schema-registry/docs/index.html)
- [README](https://github.com/confluentinc/schema-registry/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/confluentinc-schema-registry
