Skip to content

Instantly share code, notes, and snippets.

@dims
Last active May 5, 2026 12:17
Show Gist options
  • Select an option

  • Save dims/c8dd44ba82ed51dfc242b065a6ff2284 to your computer and use it in GitHub Desktop.

Select an option

Save dims/c8dd44ba82ed51dfc242b065a6ff2284 to your computer and use it in GitHub Desktop.
Kubernetes unwanted vendor dependencies status — April 2026

Kubernetes Unwanted Dependencies: Status Report

Date: May 2026
Branch: master (commit 47f990437458a2b171f51b5e97a0c28c81d949d1)
Scope: hack/unwanted-dependencies.json — modules listed in spec.unwantedModules that are still present in vendor/


Background

hack/unwanted-dependencies.json is a file in the Kubernetes repository that formalizes the list of Go modules that the project wants to eliminate. It has two top-level sections:

  • spec.unwantedModules — the authoritative blocklist of modules that must not be introduced or retained, with a rationale string for each. The blocklist currently contains 87 entries.
  • status.unwantedReferences — a record of which upstream modules (that Kubernetes vendors) still pull in each unwanted module transitively. This section is maintained manually and reflects why each unwanted module cannot yet be removed.
  • status.unwantedVendored — the list of modules currently still present in vendor/ despite being unwanted.

Of the 87 unwanted modules, 78 have been fully cleared (not in vendor/). 9 remain as of this report.

All 9 remaining modules are indirect dependencies only — every one appears as // indirect in the root go.mod. Kubernetes itself does not import them directly in production code (though k8s.io/code-generator has direct source-level imports of github.com/gogo/protobuf for its go-to-protobuf tooling).


The 9 Remaining Unwanted Modules

Module Blocklist reason
github.com/davecgh/go-spew refer to #103942 (unmaintained, replaced by stdlib diff tools)
github.com/gogo/protobuf unmaintained
github.com/golang/protobuf replace with google.golang.org/protobuf
github.com/google/btree unmaintained, archive mode
github.com/json-iterator/go refer to #105030 (unsafe reflection internals)
github.com/modern-go/concurrent problematic reliance on Go internals
github.com/modern-go/reflect2 problematic reliance on Go internals
golang.org/x/exp experimental/deprecated packages
gopkg.in/yaml.v3 prefer sigs.k8s.io/yaml/goyaml.v3

Note on coupling: github.com/modern-go/concurrent and github.com/modern-go/reflect2 are exclusively pulled in by github.com/json-iterator/go. They share all the same blockers and cannot be removed independently. They are analyzed together under the json-iterator entry.


Vendor Versions of the 9 Remaining Modules

github.com/davecgh/go-spew        v1.1.2-0.20180830191138-d8f796af33cc
github.com/gogo/protobuf          v1.3.2
github.com/golang/protobuf        v1.5.4
github.com/google/btree           v1.1.3
github.com/json-iterator/go       v1.1.12
github.com/modern-go/concurrent   v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/reflect2     v1.0.3-0.20250322232337-35a7c28c31ee  (pinned pseudo-version)
golang.org/x/exp                  v0.0.0-20251219203646-944ab1f22d93
gopkg.in/yaml.v3                  v3.0.1

Per-Module Analysis

1. github.com/davecgh/go-spew

Rationale: Unmaintained library used for "spewing" (deep-printing) Go values in test diffs. The Kubernetes project wants to remove it in favor of stdlib %#v/%+v or purpose-built diff tools.

Primary upstream blockers (from status.unwantedReferences): github.com/stretchr/testify, go.etcd.io/etcd/* (5 modules), go.etcd.io/raft/v3, go.uber.org/zap, go.uber.org/goleak, go.uber.org/multierr, go.opentelemetry.io/* (9 modules), github.com/prometheus/common, github.com/sirupsen/logrus, github.com/grpc-ecosystem/go-grpc-middleware/v2, github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus, github.com/google/cadvisor, github.com/go-logr/zapr, github.com/cyphar/filepath-securejoin, github.com/go-task/slim-sprig/v3, go.etcd.io/bbolt, k8s.io/kube-openapi, k8s.io/utils, sigs.k8s.io/kustomize/*

Kubernetes vendor versions of key blockers:

  • github.com/stretchr/testify v1.11.1
  • go.etcd.io/etcd/server/v3 v3.6.11
  • k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787 (master pseudo-version)

Upstream status:

  • stretchr/testify v1.11.1: Still has github.com/davecgh/go-spew v1.1.1 as a direct dependency in go.mod (not indirect). Issue stretchr/testify#1061 ("Possible to remove go-spew?") has been open since March 2021 and remains open. PR #1772 ("change yaml library to go.yaml.in/yaml/v3") was updated April 2026, showing active maintenance, but go-spew removal is not yet prioritized.

  • go.etcd.io/etcd/server/v3 v3.6.11 (latest): Still has github.com/davecgh/go-spew v1.1.1 // indirect.

  • k8s.io/kube-openapi (master): Still has github.com/davecgh/go-spew v1.1.1 // indirect (pulled transitively by testify, which kube-openapi uses for tests).

  • go.uber.org/zap, OTel, and others: Indirectly via testify as a test dependency; none appear to be actively removing go-spew.

Prognosis: 🔴 Blocked upstream with no near-term fix. The root blocker is stretchr/testify, which has an open issue since 2021 with no concrete plan to remove go-spew. The dependency is particularly broad — 35+ blockers. Progress is tied to the entire ecosystem switching away from testify's assert.Equal diff output, which is a very slow-moving change. No blocking PR is in flight anywhere.


2. github.com/gogo/protobuf

Rationale: Unmaintained fork of the Go protobuf API with extra code generation features. The upstream recommendation is to migrate to google.golang.org/protobuf.

⚠️ k/k itself is a direct user: staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protoc-gen-gogo/main.go imports github.com/gogo/protobuf/vanity/command, gogoproto, proto, and sortkeys directly. This is the protoc-gen-gogo code generator tool. The k8s.io/code-generator staging module declares it as a direct dependency.

Primary upstream blockers (from status.unwantedReferences): github.com/containerd/containerd/api, github.com/containerd/errdefs/pkg, github.com/containerd/ttrpc, github.com/containerd/typeurl/v2, github.com/google/cadvisor, go.etcd.io/etcd/api/v3, go.etcd.io/etcd/client/v3, go.etcd.io/etcd/server/v3, go.etcd.io/raft/v3, k8s.io/code-generator

Kubernetes vendor versions of key blockers:

  • github.com/containerd/containerd/api v1.10.0
  • github.com/containerd/ttrpc v1.2.7
  • github.com/containerd/typeurl/v2 v2.2.3
  • github.com/google/cadvisor v0.56.2
  • go.etcd.io/etcd/server/v3 v3.6.11

Upstream status:

  • containerd/ttrpc v1.2.7 / v1.2.8 (latest): Both versions still have github.com/gogo/protobuf v1.3.2 as a direct dependency. Issue containerd/ttrpc#97 ("New branch for removing gogo/protobuf") is open (last updated January 2024). The issue describes ongoing work to support gogo-free generated code, but the ttrpc library itself still depends on gogo for its current generated code. The removal would require breaking changes to the API.

  • containerd/containerd/api v1.10.0: Has github.com/gogo/protobuf v1.3.2 // indirect. Note: v1.11.0 (tagged api/v1.11.0) also retains gogo/protobuf v1.3.2 // indirect — it dropped golang/protobuf but not gogo/protobuf. Both come transitively through containerd/ttrpc and containerd/typeurl/v2.

  • containerd/typeurl/v2 v2.2.3: Has github.com/gogo/protobuf v1.3.2 (confirmed via git tree inspection).

  • google/cadvisor v0.56.2 (latest): Has github.com/gogo/protobuf v1.3.2 // indirect.

  • go.etcd.io/etcd/server/v3 v3.6.11 (latest): Has github.com/gogo/protobuf v1.3.2 as a direct dependency. On main, PR #21261 ("WIP - clean up gogo: POC") is open with several sub-tasks merged, but the overall effort is in progress. Issues #14533 and #21696 track this work. The main branch still shows gogo/protobuf v1.3.2 in server/go.mod.

  • k8s.io/code-generator: This is a Kubernetes-internal blocker. The go-to-protobuf tool is a code generator that helps generate gogo-protobuf-based code for Kubernetes API types. Removing this usage requires migrating Kubernetes' own proto generation pipeline.

Prognosis: 🔴 Multi-year effort, actively in progress but not imminent. Two distinct blocker tracks: (1) the containerd ecosystem, where ttrpc is the primary root blocker with active gogo removal work but no released version yet; and (2) etcd, where main has WIP but no release. Additionally, Kubernetes' own code-generator tool is a direct user. This module is unlikely to be removable before etcd v3.7 and a new containerd/ttrpc major release.


3. github.com/golang/protobuf

Rationale: The legacy (v1) Go protobuf API package. Since v1.5.0 it is a thin shim over google.golang.org/protobuf, but the project wants to eliminate even this shim to reduce the dep graph.

Primary upstream blockers (from status.unwantedReferences): github.com/container-storage-interface/spec, github.com/containerd/containerd/api, github.com/containerd/ttrpc, github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus, go.etcd.io/etcd/api/v3, go.etcd.io/etcd/client/v3, go.etcd.io/etcd/server/v3, go.etcd.io/raft/v3, google.golang.org/grpc, google.golang.org/protobuf, sigs.k8s.io/apiserver-network-proxy/konnectivity-client

Key vendor versions:

  • google.golang.org/grpc v1.80.0
  • sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0
  • github.com/containerd/ttrpc v1.2.7
  • github.com/container-storage-interface/spec (vendored, latest v1.12.0)

Upstream status:

  • google.golang.org/grpc v1.80.0 / v1.81.0 (latest) / master: Has github.com/golang/protobuf v1.5.4 as a direct dependency in all versions including master. In issue grpc/grpc-go#8940 (closed March 2026), the gRPC team explicitly stated: "Yes. We need to be able to support applications that are using proto generated code from older versions of the code generator... As long as we are on grpc major version 1 (and there is no plan of doing a new major version) this dependency will remain." This is a firm upstream decision: grpc-go v1.x will not drop golang/protobuf.

  • containerd/containerd/api v1.11.0: This is the key near-term progress item. The api/v1.11.0 tag dropped github.com/golang/protobuf entirely — it is no longer in go.mod. Open PR kubernetes/kubernetes#138787 ("Update gRPC ecosystem dependencies", updated May 5, 2026) bumps containerd/containerd/api from v1.10.0 → v1.11.0 and explicitly notes this in the description. The hack/unwanted-dependencies.json patch in that PR removes github.com/containerd/containerd/api from the golang/protobuf blocker list.

  • containerd/ttrpc v1.2.8 (latest): Still has github.com/golang/protobuf v1.5.4 as a direct dependency.

  • konnectivity-client v0.34.0 (tag: konnectivity-client/v0.34.0): Has github.com/golang/protobuf v1.5.4 // indirect. No newer tagged release exists; the releases page shows v0.0.9 as the most recent GitHub release, but the go module versioning uses the konnectivity-client/vX.Y.Z tag scheme.

  • google.golang.org/protobuf: Listed as a blocker because the golang/protobuf v1.5.x shim is a bridge; in practice this entry will resolve automatically when other direct users are removed.

  • container-storage-interface/spec v1.12.0: Has github.com/golang/protobuf v1.5.4 // indirect — this comes through the grpc dependency.

Prognosis: 🔴 Blocked by grpc-go's explicit long-term decision. The grpc-go maintainers have stated they will not remove golang/protobuf until a hypothetical v2 major release. Since google.golang.org/grpc is a foundational dependency of Kubernetes' entire API machinery, this module cannot be removed while Kubernetes is on grpc-go v1.x. The one near-term win is PR #138787 which removes containerd/containerd/api from the blocker list, but the core grpc-go blocker remains.


4. github.com/google/btree

Rationale: Unmaintained, in archive mode. The Go standard library has no equivalent, but k8s.io/utils has a generics-based replacement (k8s.io/utils/internal/btree).

Primary upstream blockers (from status.unwantedReferences): go.etcd.io/etcd/server/v3

Key vendor version: go.etcd.io/etcd/server/v3 v3.6.11

Upstream status:

  • go.etcd.io/etcd/server/v3 v3.6.11 (latest): Has github.com/google/btree v1.1.3 as a direct dependency in server/go.mod. Issue etcd-io/etcd#20991 ("Evaluate and replace deprecated google/btree") was closed in February 2026 — the work is done on main. Two PRs were merged into etcd's main branch: #21175 ("server: refactor btree usage to generics-based k8s.io/utils", merged January 22, 2026) and #21123 ("cache: refactor btree usage to generics-based k8s.io/utils"). The main branch of etcd/server no longer contains github.com/google/btree in go.mod.

  • The btree removal has been completed in etcd main and awaits the next etcd release (v3.7.0 or a v3.6.x patch). The etcd v3.6.11 release (current latest) predates these merges.

Prognosis: 🟡 Fix is complete in etcd main; blocked only on the next etcd release. Once etcd publishes a release including these changes and Kubernetes updates to it, this module can be removed. This is one of the clearest near-term wins. Watch for etcd v3.6.12+ or v3.7.0.


5. github.com/json-iterator/go + github.com/modern-go/concurrent + github.com/modern-go/reflect2

Rationale: json-iterator is an alternative JSON encoder/decoder that uses reflect2 (which relies on unsafe Go internals) and concurrent for performance. The project wants to use the standard library's encoding/json instead. K8s issues #105030 tracks migration within Kubernetes itself (merged in 2021); the remaining blocker is in dependencies.

Note: modern-go/concurrent and modern-go/reflect2 are pulled exclusively by json-iterator/go — they share identical blockers and disappear when json-iterator does. Analyzed together.

Primary upstream blockers (from status.unwantedReferences):

  • For json-iterator/go: github.com/prometheus/client_golang, k8s.io/kube-openapi, sigs.k8s.io/structured-merge-diff/v6
  • For modern-go/concurrent and modern-go/reflect2: same three + github.com/json-iterator/go itself

Key vendor versions:

  • github.com/prometheus/client_golang v1.23.2 (latest)
  • k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787 (master, ~May 2, 2026)
  • sigs.k8s.io/structured-merge-diff/v6 v6.3.2

Upstream status:

  • prometheus/client_golang v1.23.2 (latest): Has github.com/json-iterator/go v1.1.12 as a direct dependency. The library uses json-iterator for performance in its internal text/proto exposition format handling. No open issues or PRs in the prometheus repository about removing json-iterator were found as of this report.

  • k8s.io/kube-openapi (master, commit 7bfe71ff, May 4 2026): Still has github.com/json-iterator/go v1.1.12 // indirect and github.com/modern-go/concurrent, reflect2 as indirect. PR kubernetes/kube-openapi#326 ("use k8s.io/apimachinery/pkg/util/json instead of json-iterator/go") was closed without merging (closed November 2022, not merged). The kube-openapi master go.mod still has the indirect dep, likely pulled through sigs.k8s.io/structured-merge-diff/v6 which kube-openapi directly requires.

  • sigs.k8s.io/structured-merge-diff/v6 (master): Has github.com/json-iterator/go v1.1.12 as a direct dependency. Issue kubernetes-sigs/structured-merge-diff#202 ("remove use of json-iterator / reflect2") is open, last updated September 2025. PR #292 ("Migrate to encoding/json/v2") was opened in February 2026 and remains open (not merged). The PR shows a 38% performance regression in serialization benchmarks vs the json-iterator baseline, which is likely blocking its acceptance. The encoding/json/v2 package is still experimental.

  • The k8s-vendored version v6.3.2 (a pseudo-version beyond the v6.0.0 tagged release) still carries json-iterator/go v1.1.12 as a direct dep.

Prognosis: 🔴 Deeply entrenched; no clear near-term resolution. Three separate blockers each require independent action:

  1. prometheus/client_golang: No active removal effort found.
  2. kube-openapi: The removal attempt (PR #326) was declined; kube-openapi itself depends on structured-merge-diff which has json-iterator.
  3. structured-merge-diff: Active work (PR #292) but blocked by performance regression from switching to the experimental encoding/json/v2. This is the bottleneck for kube-openapi as well.

The structured-merge-diff PR #292 represents the most promising path but its timeline depends on encoding/json/v2 stabilizing.


6. golang.org/x/exp

Rationale: The x/exp repository holds experimental and deprecated packages. Functions it provides (like slices, maps, cmp) have been promoted to the Go standard library since Go 1.21. Code should use stdlib packages instead.

Primary upstream blockers (from status.unwantedReferences): github.com/antlr4-go/antlr/v4, github.com/google/cel-go, github.com/grpc-ecosystem/go-grpc-middleware/v2

Key vendor versions:

  • github.com/antlr4-go/antlr/v4 v4.13.1
  • github.com/google/cel-go v0.27.0 (pinned in k8s; latest upstream: v0.28.0)
  • github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3

Upstream status:

  • antlr4-go/antlr/v4 v4.13.1 (latest, released May 2024): Has golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 as a direct dependency. PR antlr4-go/antlr#15 ("fix: Remove redundant golang.org/x/exp package") is open since November 2025 and is not merged. The antlr4-go project released v4.13.1 in May 2024 and has not made a release since. Previous PRs #12 and #14 (removing x/exp slices) were closed without merging. The project appears to be sporadically maintained.

  • google/cel-go v0.28.0 (latest): Has golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect — this is pulled transitively through antlr4-go/antlr/v4. The cel-go module itself does not appear to directly use x/exp. If antlr drops x/exp, cel-go would likely follow automatically. Note: Kubernetes pins cel-go at v0.27.0 (see spec.pinnedModules in hack/unwanted-dependencies.json, pinned to fix context cancellation test failures — issue #138334).

  • grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 (latest): Has golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect. The dependency comes transitively (likely through antlr/cel via other deps).

Prognosis: 🟡 Fix is straightforward in antlr, but the project is not actively merging it. The root blocker is antlr4-go/antlr PR #15 which makes the correct fix (replacing x/exp/slices with stdlib slices) but has been open since November 2025 with no merge. The antlr project's last release was May 2024. Options: (1) nudge the antlr maintainers to merge PR #15 and cut a release, (2) fork/replace antlr in Kubernetes, or (3) accept the dependency. Since cel-go (and thereby CEL evaluation in k8s) depends on antlr, this affects a production-critical path.


7. gopkg.in/yaml.v3

Rationale: The go-yaml/yaml v3 package was archived on April 1, 2025. Kubernetes prefers sigs.k8s.io/yaml/goyaml.v3 (which wraps the maintained go.yaml.in/yaml/v3 fork from the official YAML organization).

Primary upstream blockers (from status.unwantedReferences): github.com/stretchr/testify, go.etcd.io/etcd/* (5 modules), go.etcd.io/raft/v3, go.etcd.io/bbolt, go.opentelemetry.io/* (9 modules), go.uber.org/* (3 modules), github.com/containerd/containerd/api, github.com/coreos/go-semver, github.com/cyphar/filepath-securejoin, github.com/go-logr/zapr, github.com/go-task/slim-sprig/v3, github.com/google/cadvisor, github.com/grpc-ecosystem/go-grpc-middleware/*, github.com/prometheus/common, k8s.io/kube-openapi, sigs.k8s.io/kustomize/*

Key vendor versions: (Same long tail as go-spew — effectively the entire dependency graph)

  • github.com/stretchr/testify v1.11.1
  • go.etcd.io/etcd/server/v3 v3.6.11
  • k8s.io/kube-openapi master

Upstream status:

  • stretchr/testify v1.11.1: Has gopkg.in/yaml.v3 v3.0.1 as a direct dependency. PR stretchr/testify#1772 ("change yaml library to go.yaml.in/yaml/v3") is open and was updated April 24, 2026 — it's actively being considered. The PR description notes that go-yaml/yaml was archived on April 1, 2025 and proposes migrating to the maintained fork. If merged and released, this would resolve testify's yaml.v3 dependency.

  • go.etcd.io/etcd/server/v3 v3.6.11: Has gopkg.in/yaml.v3 v3.0.1 // indirect — pulled through test dependencies. The etcd team uses testify for tests; this would cascade from a testify fix.

  • k8s.io/kube-openapi (master): Has gopkg.in/yaml.v3 v3.0.1 // indirect. The master go.mod uses go.yaml.in/yaml/v3 directly, but the old gopkg.in/yaml.v3 still appears as an indirect dep through stretchr/testify (used for tests).

  • Broad tail: Like go-spew, yaml.v3 has 30+ blockers. Most come through testify, which is the ecosystem root blocker.

Prognosis: 🟡 Better near-term outlook than go-spew. PR #1772 in testify (updated April 2026) is actively working toward migration to the maintained yaml fork. Unlike go-spew (where there's no real replacement urgency), the archival of go-yaml/yaml in April 2025 creates genuine pressure for the ecosystem to migrate. If testify merges PR #1772 and releases, it would unblock yaml.v3 for a large portion of the dependency tree.


Summary Table

Module Key blocker(s) Blocker status Prognosis
github.com/davecgh/go-spew stretchr/testify (direct dep, 35+ indirect blockers) Issue open since 2021, no active PR 🔴 Blocked long-term
github.com/gogo/protobuf containerd/ttrpc, etcd, k8s/code-generator Active WIP in etcd main; ttrpc effort stalled 🔴 Multi-year effort
github.com/golang/protobuf google.golang.org/grpc (explicit decision) grpc-go will not remove in v1.x 🔴 Blocked until grpc v2
github.com/google/btree go.etcd.io/etcd/server/v3 Removed in etcd main; awaits release 🟡 Next etcd release
github.com/json-iterator/go prometheus/client_golang, kube-openapi, structured-merge-diff SMD PR open but perf regression blocks 🔴 Blocked; SMD PR pending
github.com/modern-go/concurrent Same as json-iterator (coupled, resolves with json-iterator) 🔴 Coupled to json-iterator
github.com/modern-go/reflect2 Same as json-iterator (coupled, resolves with json-iterator) 🔴 Coupled to json-iterator
golang.org/x/exp antlr4-go/antlr (open PR #15 stalled) PR open Nov 2025, project inactive 🟡 Needs upstream nudge
gopkg.in/yaml.v3 stretchr/testify (direct dep, 30+ indirect blockers) PR #1772 open & active (April 2026) 🟡 Possible near-term if testify merges

Recommended Actions

Immediate (can act now)

  1. Track and merge k/k PR #138787 — "Update gRPC ecosystem dependencies" (open as of May 5, 2026). This bumps containerd/containerd/api to v1.11.0, which dropped golang/protobuf. It also bumps containerd/ttrpc to v1.2.8 and google.golang.org/grpc to v1.81.0. Merging this removes one entry from the golang/protobuf blocker list in unwanted-dependencies.json.

  2. Nudge antlr4-go/antlr to merge PR #15 — The PR is correct and simple (replace x/exp/slices with slices). The antlr project last released in May 2024; reaching out to maintainers or filing a release request could unblock the entire golang.org/x/exp dependency chain for Kubernetes, cel-go, and go-grpc-middleware.

Medium-term (nudge upstreams)

  1. stretchr/testify + yaml.v3: PR #1772 is active and motivated by the go-yaml archival (April 2025). Adding a comment or reaction from the Kubernetes project could help move this forward. A testify release with go.yaml.in/yaml/v3 would clear yaml.v3 for a large portion of the dep tree.

  2. sigs.k8s.io/structured-merge-diff PR #292: This is the most impactful Kubernetes-adjacent project to advance. The PR migrates to encoding/json/v2 but has a 38% serialization performance regression. Profiling and optimizing the PR, or waiting for encoding/json/v2 to mature (it's experimental), are the two paths. The SMD maintainers could also be engaged to evaluate alternative approaches (e.g., fork jsoniter or implement a stdlib-only fast path).

  3. prometheus/client_golang: Investigate whether json-iterator can be replaced with stdlib JSON. This is likely feasible for the text/proto format parser. Consider filing an upstream issue or contributing a PR.

  4. containerd/ttrpc gogo removal: Watch ttrpc#97. Once a ttrpc release drops gogo, it cascades to containerd/containerd/api and potentially other containerd modules.

Long-term (track externally)

  1. google.golang.org/grpc and golang/protobuf: The gRPC team's explicit statement (issue #8940, March 2026) is that golang/protobuf will remain for the lifetime of grpc-go v1.x. There is no plan for a grpc-go v2. Kubernetes should plan to carry this dependency indefinitely or contribute to a grpc-go v2 effort.

  2. go.etcd.io/etcd (gogo/btree): Monitor etcd main for the next release. The btree removal is complete in main. The gogo removal (PR #21261 and related issues) is active WIP. A future etcd v3.7.0 could clear both.

  3. k8s.io/code-generator (gogo direct usage): The go-to-protobuf tool is a direct user of gogo/protobuf. This will need a separate migration effort either to protoc-gen-go or a replacement tool. This is a Kubernetes-internal action that can proceed independently of upstream.


Changes Since the April 2026 Report

Based on the current state of upstream repositories, the following developments are noteworthy since a hypothetical April 2026 snapshot:

  • containerd/containerd/api v1.11.0 released (tagged api/v1.11.0): This version dropped github.com/golang/protobuf from its go.mod entirely — confirmed in this analysis. K/k PR #138787 (opened May 5, 2026) is in flight to take this version.

  • etcd btree removal landed in main (PRs #21175, #21123 merged January 2026): The github.com/google/btree module is fully removed from etcd's main branch. Issue #20991 was closed in February 2026. This is new since an April analysis would have shown only merged-but-unreleased status.

  • stretchr/testify yaml.v3 PR #1772 became active (last updated April 24, 2026): The go-yaml archival (April 1, 2025) created concrete motivation; this PR appears to have gained recent momentum.

  • etcd gogo cleanup WIP PR #21261 active (last updated April 18, 2026): Multiple sub-tasks from the WIP have been split out and merged.

  • structured-merge-diff PR #292 opened (February 2026): The encoding/json/v2 migration attempt is new since early 2026.

  • grpc-go issue #8940 closed (March 2026): The grpc-go team's explicit "will not remove in v1.x" statement is now on record and closes out the question of whether there's a near-term plan.

  • antlr4-go/antlr PR #15 remains stale (opened November 2025, no new activity): No progress since November 2025.


Methodology

All data in this report was collected using the following reproducible commands:

# Step 1: Find still-vendored unwanted modules
python3 -c "
import json, re
with open('hack/unwanted-dependencies.json') as f: data = json.load(f)
unwanted = set(data['spec']['unwantedModules'].keys())
vendored = set()
with open('vendor/modules.txt') as f:
    for line in f:
        m = re.match(r'^# (\S+) ', line)
        if m: vendored.add(m.group(1))
found = sorted(unwanted & vendored)
print(f'Still vendored ({len(found)}):')
for mod in found:
    print(f'  {mod}  ({data[\"spec\"][\"unwantedModules\"][mod]})')
"

# Step 2: Get vendor versions
grep '^# ' vendor/modules.txt | grep -E '(davecgh|gogo/protobuf|golang/protobuf|google/btree|json-iterator|modern-go|golang\.org/x/exp|yaml\.v3)'

# Step 3: Check upstream go.mod files
gh api "repos/<org>/<repo>/contents/<path>/go.mod?ref=<tag>" --jq '.content' | base64 -d | grep <pattern>

# Step 4: Check latest releases
gh api repos/<org>/<repo>/releases/latest --jq '.tag_name'

# Step 5: Search for upstream issues/PRs
gh search issues --repo <org>/<repo> "<term>" --limit 5 --json number,title,state,url
gh search prs --repo <org>/<repo> "<term>" --limit 5 --json number,title,state,url

All upstream go.mod checks were performed via the GitHub API against both the currently-vendored tag and the latest upstream release/main branch. Issue and PR details were fetched via gh issue view and gh pr view.

Prompt: Regenerate Kubernetes Unwanted Dependencies Report

The following prompt, given to Claude Code in the root of the Kubernetes repository, will reproduce an equivalent analysis:


I want a detailed status report on the unwanted dependencies still present in the
Kubernetes vendor/ directory, similar to a previous analysis done in April 2026.

Here is the full workflow to follow:

### Step 1 — Find all unwanted modules still vendored (exact match, no prefix false-positives)

Run this Python snippet:

    python3 -c "
    import json, re
    with open('hack/unwanted-dependencies.json') as f:
        data = json.load(f)
    unwanted = set(data['spec']['unwantedModules'].keys())
    vendored = set()
    with open('vendor/modules.txt') as f:
        for line in f:
            m = re.match(r'^# (\S+) ', line)
            if m:
                vendored.add(m.group(1))
    found = sorted(unwanted & vendored)
    print(f'Still vendored ({len(found)}):')
    for mod in found:
        print(f'  {mod}  ({data[\"spec\"][\"unwantedModules\"][mod]})')
    "

### Step 2 — For each remaining module, identify which direct dependencies bring it in

Read hack/unwanted-dependencies.json → status.unwantedReferences. This maps
each unwanted module to the list of our direct dependencies that pull it in.

### Step 3 — Determine current vendor versions of all primary blockers

    grep '^# ' vendor/modules.txt | grep -E '<list of primary blockers>'

### Step 4 — For each primary blocker at its current vendored version, check whether
the unwanted module is in its go.mod

    curl -s "https://raw.githubusercontent.com/<org>/<repo>/refs/tags/<version>/go.mod" \
      | grep '<unwanted-module>'

### Step 5 — Check the blocker's main/master branch for in-progress removal

    curl -s "https://raw.githubusercontent.com/<org>/<repo>/main/go.mod" \
      | grep '<unwanted-module>'

### Step 6 — Find the latest release of each blocker (to catch cases where main is
ahead of what we vendor)

    gh api repos/<org>/<repo>/releases/latest --jq '.tag_name'

Then check that latest release's go.mod too.

### Step 7 — Search for open issues and PRs in upstream repos about removal

For each blocker repo, run:

    gh search issues --repo <org>/<repo> "<short-name-of-unwanted-module>" \
      --limit 5 --json number,title,state,url
    gh search prs --repo <org>/<repo> "<short-name-of-unwanted-module>" \
      --limit 5 --json number,title,state,url

Fetch the body and latest comments of the most relevant results:

    gh issue view <number> --repo <org>/<repo> --json title,state,body,comments

### Step 8 — Compile the report

Write a 6-7 page markdown to ~/notes/k8s-unwanted-deps-<YYYY-MM>.md with:

1. Background section explaining hack/unwanted-dependencies.json
2. Table of all currently-vendored unwanted modules
3. Per-module section for each one covering:
   - Blocklist rationale
   - Primary upstream blockers (from status.unwantedReferences)
   - Upstream status (latest release still has it? main/master removed it?)
   - Known open issues and PRs in upstream repos
   - Prognosis (near / medium / long term)
4. Summary table with prognosis column
5. Recommended actions (immediate / medium-term / long-term)
6. Methodology section with reproducible shell commands
7. Appendix pointing to the prompt file in the gist

Use ✅ 🟡 🔴 to indicate status (done-unreleased / in-progress / blocked).

### Key repos to check for each module (from the April 2026 analysis):

- google/btree → etcd-io/etcd (server/v3)
- go-spew → stretchr/testify (primary), prometheus/common, go-openapi/*
- yaml.v3 → stretchr/testify (primary), same long tail as go-spew
- mailru/easyjson → kubernetes/kube-openapi → go-openapi/jsonpointer, go-openapi/swag
- json-iterator + modern-go → prometheus/client_golang, kubernetes/kube-openapi,
  kubernetes-sigs/structured-merge-diff
- gogo/protobuf → containerd/ttrpc, containerd/typeurl, google/cadvisor,
  etcd-io/etcd (server/v3)
- golang/protobuf → grpc/grpc-go (primary), containerd/containerd/api, etcd-io/etcd,
  konnectivity-client
- golang.org/x/exp → antlr4-go/antlr, google/cel-go,
  grpc-ecosystem/go-grpc-middleware

After writing the file, push both the report and this prompt file to the GitHub Gist
at https://gist.github.com/dims/c8dd44ba82ed51dfc242b065a6ff2284 using:

    gh gist edit c8dd44ba82ed51dfc242b065a6ff2284 \
      --add-file k8s-unwanted-deps-<YYYY-MM>.md \
      <path-to-report-file>

Return the gist URL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment