github emissary-ingress/emissary v4.2.0-rc.0
Emissary-ingress v4.2.0-rc.0

pre-release2 hours ago

🎉 Emissary v4.2.0-rc.0 🎉

Emissary-ingress is an open source, Kubernetes-native microservices API gateway built on the Envoy Proxy.

Get started with Emissary-ingress - https://emissary-ingress.dev/docs/4.1/quick-start/ (use --version=4.2.0-rc.0 for both charts to try this release candidate)
View changelog - https://github.com/emissary-ingress/emissary/blob/v4.2.0-rc.0/CHANGELOG.md

Changes

  • Update: Upgrade from Envoy 1.37.2 to Envoy 1.40.2 (1.38.0 release notes,
    1.39.0 release notes, 1.40.0 release notes, 1.40.2 release notes). Envoy
    1.40 changes some defaults that are visible through Emissary:
    • When ENVOY_CONCURRENCY is not set, Envoy now sizes its worker threads to
      the container's cgroup CPU limit rather than to the node's CPU count. Set
      ENVOY_CGROUP_CPU_DETECTION=false on the Emissary container to keep the old
      behaviour.
    • The x-envoy-upstream-stream-duration-ms request header is now stripped from
      external requests, like the other x-envoy-* timeout and retry headers.
    • The HTTP/1 QUERY method is now forwarded upstream rather than rejected with
      a 400.
    • Regular expressions in Mappings (prefix_regex, regex_headers,
      regex_rewrite, and so on) are now matched in Latin-1 mode rather than UTF-8
      (CVE-2026-73552).
    • X25519MLKEM768 is now one of the default TLS ECDH curves for Hosts and
      TLSContexts that do not set ecdh_curves.
    • The image's CA bundle no longer trusts the compromised eMudhra intermediate
      CAs.
  • Update: Emissary is now built with Go 1.27.3 and the Kubernetes 1.37 client
    libraries, and its other Go and Python dependencies are updated to their
    current releases. diagd now posts Ingress and other resource status
    updates from threads rather than from forked worker processes, so the
    Emissary pod no longer runs five extra diagd processes once the first
    status update is posted.

  • Security: diagd's internal API -- most importantly POST /_internal/v0/watt,
    which hands Emissary a new configuration snapshot -- is no longer reachable
    through the admin port (8877). diagd now listens on a Unix-domain socket
    (AMBASSADOR_DIAGD_SOCKET, default $AMBASSADOR_CONFIG_BASE_DIR/diagd.sock)
    rather than on TCP, and the server on 8877 refuses to proxy /_internal/ at
    all, so submitting a snapshot now requires being on the pod. Health checks and
    the diagnostics UI on 8877 are unchanged. Note that binding diagd to
    127.0.0.1 would not have been sufficient, since kubectl port-forward makes
    off-pod traffic appear to originate from 127.0.0.1.

    This removes the AMBASSADOR_DIAGD_BIND_PORT and AMBASSADOR_DIAGD_BIND_ADDREASS
    environment variables, which no longer have anything to configure.

  • Security: The snapshot is now handed to diagd directly, as the body of the
    /_internal/v0/watt request, rather than as a URL for diagd to go fetch.
    This removes the snapshot server that used to listen on localhost:9696,
    which served the unsanitized snapshot -- secrets and all -- and which was
    reachable with kubectl port-forward. (The sanitized snapshot is still
    available on 8005 as before.) It also removes an attacker-controlled fetch
    from the /_internal/v0/watt handler.

  • Fix: Completely disable the Ambassador Labs error_response_overrides mechanism;
    you'll now see an error posted if you try to use it. (This shouldn't affect anyone
    running Emissary.)

  • Fix: Weighted TCPMappings now divide traffic in the ratio they are configured with.
    Their weights were reaching Envoy as running totals rather than as each cluster's own
    share, so a pair weighted 70 and 30 actually split about 77/23. If you had tuned
    weights around the old behaviour, your split will change.

  • Fix: A ConsulResolver's datacenter is now honored. It was being ignored, so
    every lookup went to the datacenter of the Consul agent at address, and a
    resolver naming a datacenter that agent does not serve (or serves under another
    name) still resolved. Lookups now query the named datacenter; if you had a
    wrong datacenter that happened to work, it will stop resolving.

  • Fix: apiext now eagerly generates its webhook server certificate for its
    well-known Service hostname as part of its readiness check, rather than
    generating it lazily on the first incoming TLS handshake. Previously, the
    first CRD-conversion request from the Kubernetes apiserver after apiext
    reported itself ready could be the one paying for certificate generation,
    occasionally causing that request to time out (#4275).

  • Fix: Two ConsulResolvers in different datacenters that watch services with the
    same name no longer overwrite each other's endpoints. Previously only one of
    the two Mappings got endpoints (the other returned 503), and which one could
    change as either watch updated.

  • Fix: The Helm chart no longer declares the same containerPort twice when several
    service.ports share a targetPort (for example http and https both targeting 8080
    when TLS is terminated at the load balancer). Duplicate entries can make the Deployment fail to apply.
    A hostPort set on any of those service ports is kept, and different hostPort values for the
    same targetPort are rejected. (#5802)

  • Fix: Two Mappings for the same service, one using the default Kubernetes service
    resolver and one using an endpoint resolver, no longer share one Envoy cluster.
    Whichever loaded first decided the cluster type for both, so one Mapping could lose
    per-pod endpoints and its health checks, or gain them unasked. Clusters for Mappings
    with a non-default resolver now include the resolver name, so Envoy recreates them
    once on upgrade; stats names are unchanged.

  • Fix: An add_request_headers or add_response_headers entry written as an object
    with no value (for example cache-control: {append: true}) no longer crashes
    Emissary. The header is skipped and an error is logged (#4760).

  • Feature: TLSContexts and the tls settings of a Host now accept
    signature_algorithms, which is passed to Envoy alongside cipher_suites and
    ecdh_curves. Envoy's default list leaves out ed25519, so this is how to accept
    Ed25519 client certificates (#5871).
  • Feature: The emissary-crds chart can now schedule the emissary-apiext
    Deployment with apiext.nodeSelector and apiext.tolerations. Both default to
    empty, so existing installs render the same.

Don't miss a new emissary release

NewReleases is sending notifications on new releases.