Blog
Patching Go after a CA incident: CVE-2026-111943 and static trust bundles
CVE-2026-111943 tracks the Go ecosystem impact from the eMudhra weak private key incident. Go 1.27.3 and 1.26.10 include updated trust bundles. Go applications with embedded or static certificate pools require a rebuild, not just a runtime update.
Trust & PKI · Runtimes
CVE-2026-111943 is the Go ecosystem tracking identifier for the TLS trust impact of the eMudhra CA incident — specifically, that Go applications relying on the OS trust store or on Go's built-in trust bundle may accept TLS certificates signed by eMudhra's compromised EM OV TLS CA-G3C intermediate. An attacker who recovers the private key (trivial: the scalar is 4) can forge certificates that Go applications validate as trusted.
Go 1.27.3 and Go 1.26.10 are the patch releases. Both include an updated built-in certificate root store and updated logic to distrust the compromised intermediate. For Go applications that use the OS trust store, an OS-level CA update (from the Linux distribution security channel, macOS Security Update, or Windows Update) also closes the path — but only if the Go runtime's version also aligns.
Why Go is a distinct case
Go's TLS implementation (crypto/tls + crypto/x509) interacts with CA trust in three ways:
- OS trust store (default on Linux/macOS): Go reads the system CA bundle at startup. If the OS bundle has been updated to distrust the eMudhra intermediate, Go applications inherit that protection — but only after a process restart.
- Embedded trust bundle (fallback): If Go cannot find the OS trust store, it falls back to an embedded bundle compiled into the Go runtime binary. Prior to 1.27.3/1.26.10, this bundle included the eMudhra root. This embedded bundle is updated only by updating the Go runtime version.
- Application-supplied cert pool: If the application constructs a
*x509.CertPoolexplicitly (viax509.NewCertPool()+AppendCertsFromPEM()or similar), the certs in that pool are independent of both the OS and the runtime. Applications that explicitly include the eMudhra intermediate in their cert pool require a code change and rebuild.
Identifying which trust path a Go application uses
// Pattern 1: Uses system roots (reads OS trust store at runtime)
// crypto/tls default: TLSConfig with nil RootCAs field uses system pool
tlsConfig := &tls.Config{} // no RootCAs set
// Pattern 2: Uses embedded Go bundle (fallback if OS store not found)
// Behaviour is automatic -- not explicitly configured in most cases
// Pattern 3: Application-supplied cert pool -- check for this pattern
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(certBytes) // certBytes must not include eMudhra intermediate
tlsConfig := &tls.Config{RootCAs: pool}Binary inspection (without source):
# Check Go version used to build a binary
go version ./binary-name
# Strings search for embedded certificate indicators
strings ./binary-name | grep -i "emudhra\|ov tls ca\|g3c"
# Check if binary was statically linked (no OS cert store access)
ldd ./binary-name
# If "not a dynamic executable" -> statically linked -> uses embedded bundle onlyRebuild checklist
The remediation for CVE-2026-111943 in Go workloads requires more than updating a package. The checklist varies by application trust path:
| Application trust path | Required fix | Rebuild required? |
|---|---|---|
| OS trust store (default, dynamic binary) | Update OS CA package + restart application | No rebuild — process restart sufficient after OS update |
| Go embedded bundle fallback | Update Go runtime to 1.27.3 / 1.26.10 | Yes — rebuild required |
| Explicit cert pool from file/env | Remove eMudhra intermediate from cert source | Yes — code change + rebuild |
| Explicit cert pool bundled in binary | Update cert bundle in source + rebuild | Yes — code change + rebuild |
| Containerised application (any trust path) | Rebuild container image with updated base | Yes — container rebuild + redeploy |
Container rebuild scope
For containerised Go services, the rebuild requirement compounds:
# Update base image to one with updated ca-certificates
FROM golang:1.27.3-alpine3.20
# Or for multi-stage builds: update both build and runtime stages
FROM golang:1.27.3 AS builder
# ... build steps ...
FROM debian:12-slim AS runtime
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
# ca-certificates package must include the eMudhra distrust updateFinding affected Go containers in your environment:
# List running containers and their Go binary versions
docker ps -q | xargs -I{} docker exec {} sh -c 'go version 2>/dev/null || echo "no go binary"'
# Check Go version in container labels / Dockerfile metadata
docker inspect <image> | jq '.[0].Config.Labels'
# For Kubernetes: query running pods for Go-based images
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | \
sort -u | grep -i golangGo version update reference
| Current Go version | Patched version | Distribution channel |
|---|---|---|
| 1.27.x | 1.27.3 | go.dev/dl |
| 1.26.x | 1.26.10 | go.dev/dl |
| 1.25.x and earlier | End of support — upgrade to 1.26.10 or 1.27.3 | Go supports two most recent major releases |
The Go team releases security patches only for the two most recent major versions. Applications on 1.25.x or earlier must upgrade to a supported release to receive the fix for CVE-2026-111943.
Dependency inventory (module-level)
If a Go service imports a library that bundles its own CA pool (some TLS proxy libraries, gRPC interceptors, or custom HTTP client wrappers do this), the vulnerability may persist after the runtime update if the library is not also updated:
# Check go.sum and go.mod for modules that may bundle certs
go mod graph | grep -i "cert\|tls\|x509\|ca"
# Audit source for x509.NewCertPool calls in dependencies
grep -r "NewCertPool\|AppendCerts" $(go env GOPATH)/pkg/mod/ 2>/dev/null | head -50For most Go applications, the remediation path is: update Go runtime to 1.27.3 or 1.26.10, rebuild all binaries, rebuild all container images, and redeploy. Verify by checking that go version ./binary reports the updated version and that the embedded trust bundle no longer includes the compromised intermediate.
Sources
- Go 1.27.3 and 1.26.10 release notes — Go project (2026-10-21)
- CVE-2026-111943 — National Vulnerability Database (2026-10-21)
- eMudhra weak private key disclosure — Talos Intelligence (2026-10-20)