Image Roadmap — the road to 100 (demand-ranked)
Why demand, not stars#
For a hardened-container catalog, the metric that matters is "how often is this run as a container," not GitHub stars. They diverge sharply:
| Image | ⭐ stars | 🐳 Docker pulls | Reality |
|---|---|---|---|
| dive | 54k | 1.7M | laptop image-inspector — rarely containerized |
| k9s | 34k | 169k | terminal UI run locally — almost never a prod container |
| oauth2-proxy | 15k | 97M | auth sidecar — run as a container everywhere |
| pomerium | 5k | 1.6B* | identity-aware proxy — massive container use |
So popular-but-local tools (k9s, stern, dive, age) are deprioritized, and high-pull proxies/apps (oauth2-proxy, pomerium, …) are promoted.
* Docker pull counts are noisy — cumulative since inception, inflated by CI/bot pulls, and some namespaces (bitnami/*) are being deprecated. Treat as order-of-magnitude, not precise.
License lens: 🟢 permissive (MIT/BSD/Apache/MPL/ISC) add freely · 🟡 AGPL/GPL ok (precedent: loki/tempo/mimir/minio/trufflehog) · 🔴 SSPL/BUSL/EULA avoid or fork.
Build effort: Go single-binary = the proven Batch-B crank (fast). C/Rust/C++ = heavier. Node/frontend = the bwrap frontend quagmire (defer, own effort). Controllers = multi-image, run in-cluster (high demand, more work).
Tier 1 — high demand × easy Go build (do next)#
Single static Go binaries and genuinely run as containers. Best impact-per-effort.
| ✓ | Image | Upstream | License | 🐳 pulls | ⭐ | Notes |
|---|---|---|---|---|---|---|
| [x] | oauth2-proxy | oauth2-proxy/oauth2-proxy | 🟢 MIT | 97M | 15k | k8s auth sidecar, ubiquitous, CG-gated (#393) |
| [x] | flux (CLI) | fluxcd/flux2 | 🟢 Apache-2.0 | 3.8M | 8k | GitOps, CG-gated — embeds install manifests (kustomize bundle at build) |
| [x] | kustomize | kubernetes-sigs/kustomize | 🟢 Apache-2.0 | 12M | 12k | CI/CD standard, CG-gated — monorepo, kustomize/vX tag |
| [x] | sops | getsops/sops | 🟢 MPL-2.0 | — | 22k | secrets in CI, CG-gated |
| [x] | crane | google/go-containerregistry | 🟢 Apache-2.0 | — | 4k | registry ops, heavy CI use |
| [x] | kubeseal | bitnami/sealed-secrets | 🟢 Apache-2.0 | — | 9k | sealed-secrets CLI (canonical repo, not bitnami-labs 301) |
Reclassified out of Tier 1 (not clean Go single-binaries — moved to "deferred"):
- pomerium — huge demand (1.6B pulls) but
//go:embeds an arch-specific Envoy binary as its data plane → Tier-3-complexity build, own effort. - cmctl — cert-manager's
makefile-modules/klone build, no clean-Xversion injection → needs its own investigation.
Tier 2 — solid demand, easy Go CLIs#
| ✓ | Image | Upstream | License | 🐳 pulls | ⭐ | Notes |
|---|---|---|---|---|---|---|
| [x] | helmfile | helmfile/helmfile | 🟢 MIT | — | 5k | declarative Helm, CD pipelines |
| [x] | regctl | regclient/regclient | 🟢 Apache-2.0 | — | 2k | registry client, CI |
| [x] | stern | stern/stern | 🟢 Apache-2.0 | — | 5k | multi-pod log tail (borderline: often local) |
| [x] | kube-vip | kube-vip/kube-vip | 🟢 Apache-2.0 | — | 3k | control-plane VIP + LB for bare metal — shipped; runs as root (NET_ADMIN/NET_RAW for netlink+ARP) |
Tier 3 — high demand, heavier builds (deliberate; fills thin DB/proxy/app categories)#
Real container demand, but C/Rust/C++/Node — each is its own effort, not a crank. Sequence by effort. Fills the catalog's thinnest categories (databases, proxies, apps).
| ✓ | Image | Upstream | License | Build | 🐳 pulls | ⭐ | Notes |
|---|---|---|---|---|---|---|---|
| [x] | pgbouncer | pgbouncer/pgbouncer | 🟢 ISC | C | 20M | 4k | Postgres pooler (thin DB cat) — shipped; underscore tags (tag-rewrite) |
| [x] | unbound | NLnetLabs/unbound | 🟢 BSD | C | 12M | 5k | DNS resolver — shipped; --sbindir=/usr/bin, builtin evloop, local-data smoke test |
| [ ] | varnishcache/varnish-cache | 🟢 BSD | C | 21M | 4k | Deferred → see below. varnishd compiles VCL with cc at runtime → needs gcc+binutils+headers in prod (breaks the shell-less/minimal thesis). |
|
| [ ] | apisix | apache/apisix | 🟢 Apache-2.0 | C/Lua/OpenResty | 37M | 17k | API gateway (harder: OpenResty) |
| [x] | vaultwarden | dani-garcia/vaultwarden | 🟡 AGPL-3.0 | Rust | 304M | 64k | self-hosted Bitwarden — shipped |
| [ ] | kvrocks | apache/kvrocks | 🟢 Apache-2.0 | C++ | 3.5M | 4k | Redis-on-RocksDB |
| [x] | patroni | patroni/patroni | 🟢 MIT | Python | — | 9k | Postgres HA — shipped; first Python-daemon pattern |
| [ ] | woodpecker | woodpecker-ci/woodpecker | 🟢 Apache-2.0 | Go+frontend | 2.7M | 7k | CI server (has web UI) |
| [x] | zipkin | openzipkin/zipkin | 🟢 Apache-2.0 | JVM-jlink | 60M | 17k | distributed tracing — shipped; Spring Boot fat jar EXPLODED so its 157 bundled jars are scannable/patchable |
Deferred / heavier efforts (own project, not a batch)#
| Image | Reason |
|---|---|
| varnish | varnishd compiles VCL → C → .so by invoking cc at runtime (VCC_CC="exec cc … -fpic -shared -o %o %s"), on every config load. A working prod image must therefore ship gcc + binutils + C headers + varnish's headers — a permanent compiler/attack-surface that breaks the "no compiler, minimum packages" thesis (Chainguard ships the toolchain for the same reason). Revisit only as a deliberate, documented exception, or pick a compiler-free HTTP-cache alternative. |
| kubescape | Go, but a large build — needs ~40 G local disk freed (stale /tmp/bubblewrap-guest-*). Recipe already generated in batch-b; onboard once disk allows. |
| pomerium | 1.6B pulls but //go:embeds an arch-specific Envoy binary (data plane). Needs an Envoy-fetch step + cross-arch handling — Envoy-image-class effort, not a clean crank. |
| cmctl | cert-manager's makefile-modules/klone build; no clean -X version injection. Needs its own investigation of the version mechanism. |
| cert-manager (core) | Multi-image (controller + webhook + cainjector + startupapicheck + acmesolver). High demand, in-cluster. Mirror the upstream image split — own effort after Tier 1. |
| flux (controllers) | source/kustomize/helm/notification-controller, separate repos. Multi-image, in-cluster. Own effort. |
| uptime-kuma | 166M pulls (MIT) but Node/yarn frontend → the bwrap frontend quagmire (see grafana). Backend-from-source + prebuilt frontend assets, own effort. |
| argocd | Embeds a yarn-built React UI and repo-server needs git/helm/kustomize at runtime (fights distroless). Grafana-bucket effort. |
Deprioritized — popular but low container demand (laptop / CLI / embedded)#
k9s (terminal UI) · dive (image inspector) · age (local crypto CLI) · duckdb
(embedded lib, not a server) · zig/erlang/lua (languages — official base images exist).
Add later only on explicit demand.
Avoided — non-OSS licenses (🔴)#
MongoDB / Elasticsearch (SSPL) · CockroachDB / Dragonfly (BSL). Use permissive forks if a
real need appears (e.g. kvrocks/valkey cover the Redis/BSL gap).
Existing 🔴 exposures to resolve (pre-existing, tracked separately)#
redis-slimdeclares SSPL-1.0 but 8.x is tri-licensed → re-declare AGPL-3.0-only.consul2.0.0 = BUSL-1.1 (no OSS fork) → keep-vs-drop decision pending.
Road to 100 — remaining batches (F–K), policy × usage × license#
Ordered by our proven build templates first (fastest impact-per-effort), then demand. Policy filter = buildable under the shell-less/minimal thesis: ✅ static-Go binary · clean C daemon (no runtime compiler — the varnish lesson) · JVM-jlink · interpreter · binary-repackage. Excluded from the 100-path: frontend-in-bwrap (grafana/argocd/uptime-kuma), runtime-compiler (varnish), tangled force-bump graphs, huge-disk C++ (clickhouse), and 🔴 SSPL/BUSL/EULA. This section is a completed build log — the 100 target was reached and the catalog now stands at 108.
Batch F — static Go (the crank) → 88 [DONE]#
| Image | Upstream | License | Build notes |
|---|---|---|---|
| external-dns | kubernetes-sigs/external-dns v0.21.0 | 🟢 Apache | main ., CGO=0, -X …/pkg/apis/externaldns.Version |
| velero | vmware-tanzu/velero v1.18.2 | 🟢 Apache | main ./cmd/velero, CGO=0, …/pkg/buildinfo.Version |
| kaniko | GoogleContainerTools/kaniko v1.24.0 | 🟢 Apache | main ./cmd/executor (binary executor → /kaniko/executor), …/pkg/version.version |
| step-ca | smallstep/certificates v0.30.2 | 🟢 Apache | main ./cmd/step-ca, CGO=0 (drops pkcs11 KMS), -X main.Version; server |
| skopeo | containers/skopeo v1.23.0 | 🟢 Apache | module go.podman.io/skopeo; CGO=0 + -tags containers_image_openpgp drops libgpgme/btrfs |
Batch G — clean C daemon (pgbouncer/unbound template) → 93 [DONE]#
| Image | Upstream | License | Build notes |
|---|---|---|---|
| dnsmasq | Wolfi dnsmasq 2.93 |
🟡 GPL-2.0-or-later | apko-only — Wolfi packages it, so no melange recipe and no versions.yaml row (classified wolfi-rolling). Flag-driven: the package ships no config and apko cannot author file contents, so --conf-file= disables config lookup and --log-facility=- moves logs off syslog. |
| keepalived | acassen/keepalived 2.4.3 | 🟡 GPL-2.0-or-later | source-built; --disable-dbus --disable-snmp --with-init=none, --sbindir=/usr/bin (usrmerge). Needs CAP_NET_ADMIN/NET_RAW/NET_BROADCAST at runtime — still runs as nonroot 65532. github-tags needs strip-prefix: 'v', not strip-v (that key is only read by other source types). |
Fills thin Infrastructure.
Batch H — JVM-jlink (kafka/zookeeper template)#
cassandra (🟢 wide-column DB, Java-17 + jamm agent) · solr (🟢 search, Java-21) · pulsar (🟢 messaging, Java-21) · flink (🟢 stream processing, Java-21) — all DONE. All Apache. Fills thin DB/search/messaging.
Batch I — Rust (qdrant/vector precedent, own effort each)#
vector (🟢 MPL-2.0, observability pipeline) · vaultwarden (🟡 AGPL-3.0, Bitwarden server; ~304M pulls) — both DONE.
Batch J — Erlang / Python#
patroni (🟢 MIT, Postgres HA — new Python-daemon pattern) — DONE. couchdb (🟢 Apache, Erlang — rabbitmq precedent) remaining.
Batch K — own-effort revisit#
cmctl (🟢 Apache — revisit klone build) · + one of {cert-manager core (multi-image) / pomerium (Envoy fetch) / apisix (OpenResty)}.
Batches H–K name more candidates than the 4 slots left to 100; the last slots go to whichever land first.
Beyond the 100-path (deliberate exceptions, not scheduled): varnish (runtime cc), grafana/argocd/uptime-kuma (frontend-in-bwrap), clickhouse/kubescape (disk-cap). See the deferred table above.
Wave 2 — beyond 108 (demand-ranked, re-surveyed 2026-08-30)#
Candidate survey after the 100 target was met. Same lens as above (license ·
container demand · use case), with one new input: many of these already have a
Wolfi package, which moves them from "own effort" into the cheapest bucket we
have (apko-only, dnsmasq/vector precedent — no melange recipe, no
versions.yaml row, just an autoupdate-coverage.yaml classification).
Pull counts are Docker Hub pull_count read on 2026-08-30; treat as
order-of-magnitude (cumulative, CI/bot-inflated).
Tier W1 — apko-only from an existing Wolfi package (cheapest crank)#
Verified present in the Wolfi x86_64 APKINDEX on 2026-08-30. (v) = versioned
package ⇒ wolfi-versioned; (r) = unversioned/rolling ⇒ wolfi-rolling.
| ✓ | Image | Wolfi package | License | 🐳 pulls | Category | Notes |
|---|---|---|---|---|---|---|
| [ ] | wordpress | wordpress (r) + wordpress-oci-entrypoint |
🟡 GPL-2.0-or-later | 1.5B | Apps | Largest single demand number in the survey. Pairs with our php/httpd; Wolfi ships the OCI entrypoint too. Fills the thinnest category (Apps, 6). |
| [ ] | sonarqube | sonarqube (r) |
🟡 LGPL-3.0 | 1.2B | K8s, CI & IaC | Community Build. Heavier than it looks — bundles Elasticsearch and needs an external Postgres; smoke test = boot + /api/system/status. |
| [ ] | nextcloud | nextcloud-server-33 (v) |
🟡 AGPL-3.0 | 1.0B | Apps | AGPL precedent already set (loki/tempo/mimir/minio/vaultwarden). PHP-FPM. |
| [ ] | maven | maven-3.9 (v) |
🟢 Apache-2.0 | 767M | Languages & Runtimes | Build-tool image on top of our java. Near-zero effort, very high demand. |
| [ ] | kong | kong (r) + kong-entrypoint |
🟢 Apache-2.0 | 359M | Web Servers & Proxies | The Wolfi package removes the OpenResty/Lua build problem that keeps apisix deferred. Fills a thin category (8). |
| [ ] | neo4j | neo4j-2025.12 (v) |
🟡 GPL-3.0 | 322M | Databases | Graph DB — a category we have zero coverage of. GPL precedent: dnsmasq, keepalived. |
| [ ] | gradle | gradle-9 (v) |
🟢 Apache-2.0 | 300M | Languages & Runtimes | Same shape as maven. |
| [ ] | perl | perl (r) |
🟡 Artistic-1.0 / GPL-1.0+ | 255M | Languages & Runtimes | Trivial; the last mainstream scripting runtime we're missing. |
| [ ] | couchdb | couchdb-3.3 (v) |
🟢 Apache-2.0 | 205M | Databases | Already named in Batch J as an Erlang source build — the Wolfi package makes it a W1, not an own-effort. |
| [ ] | argo-cd | argo-cd-3.2 + -repo-server (v) |
🟢 Apache-2.0 | 148M | K8s, CI & IaC | Re-opens a deferred item. Wolfi packaging removes the yarn-frontend build; the repo-server's runtime git/helm/kustomize needs still apply, so this is multi-image, not one. |
| [ ] | rust | rust-1.92 (v) |
🟢 MIT OR Apache-2.0 | 143M | Languages & Runtimes | Toolchain image (builder-shaped, like our go). |
| [ ] | erlang | erlang-28 (v) |
🟢 Apache-2.0 | 65M | Languages & Runtimes | Natural companion to rabbitmq. |
| [ ] | meilisearch | meilisearch (r) |
🟢 MIT | 51M | Databases | Rust search engine; complements opensearch/solr at a much smaller size. |
| [ ] | temporal | temporal (r) |
🟢 MIT | 47M | Apps | Durable-execution server. Wolfi also has temporal-ui-server-oci-entrypoint if we want the UI later. |
Also packaged in Wolfi, parked deliberately: argo-workflows (🟢 Apache — take
with argo-cd or not at all), harbor-2.14-* (🟢 Apache, but 5+ images — own
effort like cert-manager), mattermost-11.4 (⚠️ mixed AGPL + Mattermost Source
Available License in the same tree — needs a license read before onboarding),
apisix-ingress-controller (🟢 Apache — note Wolfi packages the controller,
not apisix itself, so the Tier-3 apisix entry above is unchanged).
Wave 3 survey — verified 2026-09-07#
Re-checked every W1/W2 candidate against the live Wolfi APKINDEX (120,016
packages) and a Chainguard free-tier probe, after the W1 table was found wrong
twice: it listed a gitlab-runner-18.11 package that was actually
gitlab-agent-* (a different product), and a bare-name APKINDEX grep misses
versioned packages entirely. Method that actually works — check three things,
not one:
grep -x "P:<name>" APKINDEX # exact package name
grep -E "^P:<name>-[0-9]" APKINDEX # versioned package (gitlab-runner-19.3)
grep -E "^p:(.* )?<name>=" APKINDEX # a DIFFERENT package that provides the name
The Chainguard probe (validated against known-free nginx/python/static, which
all return 200) is an anonymous pull-token request against
cgr.dev/v2/chainguard/<name>/manifests/latest.
Already free from Chainguard — dropped from the plan. These were the roadmap's "near-zero effort, very high demand" picks, and there is no reason to publish a second free hardened build of something already free elsewhere:
| Image | 🐳 pulls | Why dropped |
|---|---|---|
| wordpress | 1.5B | cgr.dev/chainguard/wordpress returns 200 anonymously |
| maven | 767M | free |
| gradle | 300M | free |
| rust | 143M | free |
Gated on Chainguard and packaged in Wolfi — the cheap, high-demand bucket. Pull counts read from Docker Hub on 2026-09-07:
| Image | 🐳 pulls | License | Category | Note |
|---|---|---|---|---|
| sonarqube | 1.3B | 🟡 LGPL-3.0 | K8s, CI & IaC | Heavier than the packaging suggests: bundles Elasticsearch, needs an external Postgres |
| nextcloud | 1.1B | 🟡 AGPL-3.0 | Apps | nextcloud-server-33 (+ -apache2-config). PHP-FPM |
| kong | 360M | 🟢 Apache-2.0 | Web Servers & Proxies | The Wolfi package removes the OpenResty/Lua build that keeps apisix deferred |
| neo4j | 323M | 🟡 GPL-3.0 | Databases | Graph DB — a category with zero coverage today |
| perl | 255M | 🟡 Artistic/GPL | Languages & Runtimes | Trivial; the last mainstream scripting runtime missing |
| couchdb | 205M | 🟢 Apache-2.0 | Databases | |
| erlang | 66M | 🟢 Apache-2.0 | Languages & Runtimes | Companion to rabbitmq |
| meilisearch | 52M | 🟢 MIT | Databases | Rust search engine, much smaller than opensearch/solr |
| temporal | 48M | 🟢 MIT | Apps | Durable execution; fills the thinnest category |
| argo-cd · cert-manager · keda · karpenter · harbor · zot | — | 🟢 Apache-2.0 | K8s, CI & IaC | All in Wolfi, all gated on Chainguard. No pull counts exist — they publish to quay/ghcr/registry.k8s.io, so demand cannot be ranked the way the rest of this table is |
The finding that shapes the next wave: the source-built well has run dry at the top of the demand curve. Every remaining high-demand candidate is either Wolfi-packaged (so apko-only), blocked by a frontend build (alloy, authelia, woodpecker), or already free from Chainguard. What is left to build from source is genuinely hard and much lower demand: influxdb (1.2B, but that number is v1/v2 — current upstream is a Rust rewrite), kvrocks (3.5M, C++), apisix (37M, OpenResty), emqx (Erlang, licence read needed), timescaledb (split licence), pgadmin4 (Python + prebuilt frontend), fluentd (Ruby).
So Wave 3 is a decision, not a queue: continue insisting on source builds
and accept far lower demand per unit of effort, or take the apko-only route for
things Chainguard gates. Note that apko-only is not a weaker product here — the
Wolfi package is free, Chainguard's image is not, so a hardened signed
SBOM-attested rebuild of a gated image is exactly the gap this catalogue
exists to fill. It also keeps full auto-update coverage via
autoupdate-coverage.yaml, which check-autoupdate enforces.
Tier W2 — source-built Go (the proven crank; no Wolfi package)#
| ✓ | Image | Upstream | License | 🐳 pulls | Category | Notes |
|---|---|---|---|---|---|---|
| [x] | gitlab-runner | gitlab-org/gitlab-runner | 🟢 MIT | 3.6B | K8s, CI & IaC | Shipped — source-built. Wolfi does ship it as the versioned gitlab-runner-19.3, which p:-provides the bare name, so provider-priority: 100 was mandatory; without it apko silently installed Wolfi's binary over ours. versions.yaml uses type: json against the GitLab tags API. |
| [x] | buildkit | moby/buildkit | 🟢 Apache-2.0 | 1.8B | K8s, CI & IaC | Shipped — source-built. provider-priority: 100 needed too (Wolfi's buildkitd provides buildkit). buildkitd is the only CGO_ENABLED=1 build in the catalogue, to keep upstream's seccomp tag; libseccomp-static keeps it static. Runs as root — it refuses unprivileged uids, and the rootless path needs setuid newuidmap Wolfi does not ship setuid. |
| [ ] | grafana/alloy | 🟢 Apache-2.0 | 388M | Observability | Blocked — frontend-in-bwrap, verified 2026-09-06. internal/web/ui/dist is NOT committed; assets_builtin.go is behind //go:build embedalloyui whose go:generate runs npm ci && npm run build, and the !embedalloyui fallback serves from a runtime filesystem path that will not exist in the image. So there is no UI-bearing build without npm in the sandbox. Demand is real (inherits EOL promtail 2.8B + grafana-agent 470M) — reconsider if we ever take on a frontend build pattern. |
|
| [ ] | authelia/authelia | 🟢 Apache-2.0 | 81M | Web Servers & Proxies | Blocked — frontend-in-bwrap, verified 2026-09-06. internal/server/public_html contains only 3 files (index.html + the openapi pair); the React bundle is built from web/ by pnpm and is not in the tarball. Same blocker as alloy. |
|
| [x] | syncthing | syncthing/syncthing | 🟢 MPL-2.0 | 346M (two repos) | Infrastructure | Shipped — confirmed the easiest build in this table. CGO_ENABLED=0 picks the pure-Go modernc.org/sqlite driver v2.x needs; the web GUI is .gitignore'd upstream and regenerated by script/genassets.go, which is plain Go — no npm step. Built -tags noupgrade like upstream's own container. |
| [x] | nsq | nsqio/nsq | 🟢 MIT | 63M | Caches, Queues & Messaging | Shipped — was indeed about an hour. Ships all nine upstream binaries for drop-in parity with nsqio/nsq; nsqadmin's web assets are committed pre-built and pulled in via go:embed. Note upstream is quiet (v1.3.0, Dec 2023), so its auto-update loop will be idle by design. |
Tier W3 — heavier / needs a decision#
| Image | Why it's not W1/W2 |
|---|---|
| influxdb | 1.1B pulls on library/influxdb, but that number is v1/v2 (Go, MIT); current upstream is InfluxDB 3 Core in Rust (🟢 Apache-2.0), no Wolfi package, and our time-series slot is already served by prometheus/mimir/victoria-metrics/thanos. Worth it only if we want line-protocol coverage. |
| emqx | 47M pulls, but the repo is NOASSERTION (Apache core + BSL-ish enterprise pieces) and it's a large Erlang build. License read required first. |
| timescaledb | 123M pulls, but the tree is split Apache-2.0 / TSL (source-available) — an Apache-only build is possible and is the only version we could ship. Own effort. |
| pgadmin4 | 444M pulls (🟢 PostgreSQL license), Python + prebuilt frontend. Plausible via pip wheels; needs its own investigation. |
Confirmed avoid (🔴 non-OSS) — checked in this survey#
terraform (492M) · vault (554M) · nomad · boundary · waypoint — all
BUSL-1.1; already covered by our opentofu and openbao. elasticsearch /
kibana / logstash — Elastic License; covered by opensearch. redpanda
(35M) — BSL. n8n — Sustainable Use License. No change to the policy.
Suggested first PR out of this survey#
Six images, all W1, no new build template, spanning four categories: gitlab-runner · wordpress · maven · gradle · kong · perl — the two largest demand numbers we're missing, the two cheapest Languages entries, and the first addition to Web Servers & Proxies since oauth2-proxy.
Execution model#
- One PR per tier group (~6–8 images). Each image: 10 registration points
(see
docs/onboarding.md) incl. a validatedcron-enabledversions.yamlrow — thecheck-autoupdategate blocks the PR otherwise. - Build and prod+dev smoke-test every image locally before push (
make <img>,make test-<img>, and assemble+test the-devvariant). Never push a failing image. - Registration inserts use Python (newline-safe), not bash
$(...)(which strips newlines and glues YAML lines — same failure family as the batch-b dropped paren).