Aiven-Open / Aiven-Open/karapace
Unknown routes return non-Confluent-shaped 404 (`"Not Found"` JSON string), breaking Confluent JS client v1.9.0+
- Langage dominant
- Python
- Étoiles
- 634
- Forks
- 110
- Merge moyen
- 4 j 7 h
- PR mergées (30 j)
- 4
Description
# What happened?
Karapace's registered Schema Registry routes return Confluent-compatible JSON error bodies (`{error_code, message}` with `Content-Type: application/vnd.schemaregistry.v1+json`). However, **unregistered routes return a bare JSON string** (`"Not Found"` with `Content-Type: application/json`).
This breaks `@confluentinc/schemaregistry` v1.9.0, which added a probe to the `/associations/resources/{namespace}/{name}` endpoint during every serialize call. Karapace doesn't implement that endpoint yet (it's part of the upstream Schema Registry API — see [`confluentinc/schema-registry` Swagger spec](https://github.com/confluentinc/schema-registry/blob/master/core/generated/swagger-ui/schema-registry-api-spec.yaml#L2703) — but isn't surfaced in Karapace). The client is *designed* to treat a 404 from this endpoint as "no associations, fall back to the configured subject-name strategy" — but only when the 404 response matches Confluent's body shape. Karapace's bare-string body fails that check, so the fallback never fires and serialization fails.
Net effect: every Avro/Protobuf/JSON-Schema producer using v1.9.0+ of the Confluent JS client fails against Karapace, regardless of whether anyone is using the Associations feature.
**Reproduction** against a stock Karapace 6.1.4:
```
$ curl -i 'http://localhost:8081/associations/resources/%2A/some-topic'
HTTP/1.1 404 Not Found
Content-Type: application/json
Server: uvicorn
"Not Found"
```
```
$ curl -i 'http://localhost:8081/this-endpoint-does-not-exist'
HTTP/1.1 404 Not Found
Content-Type: application/json
Server: uvicorn
"Not Found"
```
For contrast, a registered route with a missing resource returns Confluent-shaped JSON correctly:
```
$ curl -i 'http://localhost:8081/subjects/does-not-exist/versions/latest'
HTTP/1.1 404 Not Found
Content-Type: application/vnd.schemaregistry.v1+json
Server: uvicorn
{"error_code":40401,"message":"Subject 'does-not-exist' not found."}
```
So the gap is specifically the 404 path for unregistered routes.
**Why this breaks the Confluent JS client:** the client's `RestService` only wraps an axios error as `RestError` when the response body has `error_code` and `message` fields. A bare JSON string fails that check and gets wrapped as a generic `Error("Unknown error: ...")` instead. The `serde.js` `loadSubjectName` path explicitly catches `RestError` with `status === 404` as "no associations, fall back to default subject-name strategy" — but with a generic `Error`, the `instanceof RestError` check fails and the error propagates, breaking every `producer.send()`.
# What did you expect to happen?
Two possible directions, in order of effort:
1. **Short-term fix:** unregistered-route 404 responses (and ideally any other framework-default error responses) match the Confluent `{error_code, message}` shape with `Content-Type: application/vnd.schemaregistry.v1+json`. This unblocks all Confluent JS client v1.9.0+ users immediately and likely benefits other clients too.
2. **Longer-term:** implement the `/associations/...` endpoints since they're part of the upstream SR API. Out of scope for this issue, but worth flagging as a downstream consequence of the JS client now relying on it.
# What else do we need to know?
- Karapace: **6.1.4** (latest)
- `@confluentinc/schemaregistry`: **1.9.0**
- Related: #1154 — same flavor of problem on a different code path (leader-to-follower error forwarding returns plaintext `Internal Server Error`). Possibly worth addressing under a shared "all error responses Confluent-shaped" invariant.
- Workaround for affected users: pin `@confluentinc/schemaregistry` to `1.8.2` until a fix lands.
Guide de contribution
Ouvrir le guide de contribution
Évaluation
Cette issue n'a pas encore été évaluée.