You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
apps API: Accept with protobuf first and JSON as a fallback gets 406 instead of JSON #5297
A client that prefers protobuf and accepts JSON as a fallback gets 406 Not Acceptable from the apps API instead of a JSON answer. GET on an Application with Accept: application/vnd.kubernetes.protobuf, application/json;q=0.9 returns 406. With application/cbor, application/json;q=0.9 the same request returns JSON. TestAppsAPIContentNegotiation in pkg/cmd/server/apiserver_surface_test.go (#4869) pins both answers as they are today.
The cause is that the apps API advertises a media type it cannot encode. pkg/apiserver serves through serializer.NewCodecFactory(Scheme), wrapped in kindPreservingSerializer, and that factory lists protobuf among its supported media types. Negotiation in k8s.io/apiserver picks the best match from that list, so protobuf wins over the JSON fallback. Encoding then fails because the Application types do not implement the protobuf marshalling interface. The protobuf serializer reports that as errNotMarshalable, whose status is 406 (k8s.io/apimachinery pkg/runtime/serializer/protobuf/protobuf.go), and the response never goes back to JSON. CBOR is not in the factory's list, so negotiation skips it and the fallback works.
Upstream custom resources behave the same way. apiextensions-apiserver also lists protobuf for them, because some objects it returns, like Status, do support it. So this is not specific to cozystack, but the result still breaks the Accept header's promise: JSON was acceptable and the server had it.
Two ways to handle it:
Drop protobuf from the media types the apps group negotiates, so a fallback in Accept is honoured. Objects like Status that the apps API returns would then be served as JSON too, which needs checking against clients that send protobuf only.
Keep the upstream behaviour and treat the pinned 406 as the contract. The test already describes the mechanism, so only this issue would close.
I'd go with the first, but it is a change to what the API advertises, so it needs a maintainer decision.
Activity