Skip to content

Retries to a reselected endpoint drop the Host-derived SNI #1055

Description

@shaneutt

Description

When a TLS cluster has no explicit sni configured, the initial upstream
selection falls back to the request's Host header for SNI (stripped of port,
per RFC 6066). ClusterEntry::build_upstream does this here:
load_balancer/entry.rs:78.

The retry path does not. When a retry reselects an alternate endpoint,
upstream_peer.rs:126
calls EndpointReselector::build_upstream(addr), which takes no request context
and just clones the cluster TLS as-is
(load_balancer/reselector.rs:77).
So a cluster relying on the Host-header SNI fallback connects with the correct
SNI on the first attempt but with none on an alternate-host retry.

The reselector already carries the authority (Host rewrite) across retries for
exactly this reason (its field doc notes it is kept "so a retry to a reselected
endpoint keeps rewriting Host instead of silently reverting"), but the derived
SNI was not carried, so the two paths diverge.

Impact: TLS handshakes to the upstream can fail or select the wrong certificate
during failover, which is precisely when retries fire.

Steps to reproduce

  1. Configure a cluster with TLS but no explicit sni, and more than one healthy
    endpoint, so the Host header supplies the SNI.
  2. Send a request whose first attempt fails in a way that triggers an
    alternate-host retry (e.g. a connect failure).
  3. The retry connects to the reselected endpoint without SNI, unlike the first
    attempt.

Expected behavior

Alternate-host retries apply the same Host-derived SNI fallback as the initial
selection. The reselector's build_upstream needs the request Host (or the
SNI resolved at first selection) so it can set SNI the way
ClusterEntry::build_upstream does.

Praxis version: main (v0.5.3 line)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions