Code change:
container.Add(ws) } <ins> // stripVersionEncoder strips APIVersion field from the encoding output. It's // used to keep the responses at the discovery endpoints backward compatible // with release-1.1, when the responses have empty APIVersion. type stripVersionEncoder struct { encoder    runtime.Encoder serializer runtime.Serializer } func (c stripVersionEncoder) EncodeToStream(obj runtime.Object, w io.Writer, overrides ...unversioned.GroupVersion) error { buf := bytes.NewBuffer([]byte{}) err := c.encoder.EncodeToStream(obj, buf, overrides...) if err != nil { return err } roundTrippedObj, gvk, err := c.serializer.Decode(buf.Bytes(), nil, nil) if err != nil { return err } gvk.Group = "" gvk.Version = "" roundTrippedObj.GetObjectKind().SetGroupVersionKind(gvk) return c.serializer.EncodeToStream(roundTrippedObj, w) } // StripVersionNegotiatedSerializer will return stripVersionEncoder when // EncoderForVersion is called. See comments for stripVersionEncoder. type StripVersionNegotiatedSerializer struct { runtime.NegotiatedSerializer } func (n StripVersionNegotiatedSerializer) EncoderForVersion(serializer runtime.Serializer, gv unversioned.GroupVersion) runtime.Encoder { encoder := n.NegotiatedSerializer.EncoderForVersion(serializer, gv) return stripVersionEncoder{encoder, serializer} } func keepUnversioned(group string) bool { return group == "" || group == "extensions" } </ins> // Adds a service to return the supported api versions at /apis. func AddApisWebService(s runtime.NegotiatedSerializer, container *restful.Container, apiPrefix string, f func(req *restful.Request) []unversioned.APIGroup) { <del> rootAPIHandler := RootAPIHandler(s, f) </del> <ins> // Because in release 1.1, /apis returns response with empty APIVersion, we // use StripVersionNegotiatedSerializer to keep the response backwards // compatible. ss := StripVersionNegotiatedSerializer{s} rootAPIHandler := RootAPIHandler(ss, f) </ins> ws := new(restful.WebService) ws.Path(apiPrefix) ws.Doc("get available API versions")

Related discussion:
text: That address also returns a versioned object, which at release 1.1 is unversioned: Do we need to keep all unversioned objects unversioned, or do we only need to ensure the server returns unversioned object at api/?
cc
Per our versioning rules, we should expect a v1.2 server to remain backward compatible with v1.1 clients. I don't have much experience with the api machinery, but if clients weren't expecting an unversioned object, it seems like we can't up and switch to versioned objects.
I think we have to maintain compatibility somehow. any ideas for a fix other than the obvious one?
Yes, we have to maintain backward compatibility with 1.1 (and 1.0) clients. New paths that old clients didn't know about could behave differently than paths that existed in previous releases.
Nope, let's make sure we leave a test and comment.
We can't make the change here though, this would break "versioned unversioned" objects (like )
The other implication of course is now we "versioned unversioned" objects (v1 status) and "unversioned unversioned", which means we shouldn't ever add new objects that don't return a version. I don't think anything in 1.2 qualifies as a new object without a version, just 1.1 objects that didn't have correct versions. Having objects from extensions group be returned without versions terrifies me - I don't see any way of describing that except as a bug.
We may need per API group version rules registered on scheme about whether "unversioned" objects are returned in their scheme version or as empty. That's probably the backward compatible fix that gives us a hope of reasoning about behavior correctly (status in 1.0 is v1, status in extensions might be "", apiversions in any new group is "v1"). The unversioned marker on the objects should ensure 1.2 clients can receive objects in both "" and "v1" form, we should add a test to verify that. I'm against letting empty API versions spread, but agree backcompat for existing groups versions should match previous behavior.
Can we make (or use) a different serializer/codec just for the endpoints that 1.1 clients used?