rqlite preserves hostnames when node addresses change
rqlite 7.3.0 stops resolving configured hostnames into stored IP addresses. The change preserves the name an operator supplied so later network connections can follow its current address.
A hostname can remain stable while the machine or container behind it acquires a different IP address. Resolving that name once and retaining the numeric result removes the indirection the operator intended to use. rqlite 7.3.0, released on February 5, changes its networking to preserve supplied hostnames. Resolution moves to the low-level networking layer, where it can occur when establishing a connection.
The release changelog identifies environments such as Kubernetes StatefulSets as a motivation. A node can retain its stable name while its address changes. The change does not require every deployment to use hostnames. A process supplied with an explicit IP address continues to use that address as its configured network identifier.
I value rqlite's small operational footprint, and this is a useful reduction in deployment-specific handling. A stable node name should remain meaningful to the database cluster. Converting it into one startup-time address makes a deployment abstraction disappear at exactly the point where a replacement instance needs it to remain available.
The join request retains the supplied address
The implementation change in pull request 993 removes early resolution from the join path. Previously, the join code called net.ResolveTCPAddr on the joining node's address and placed the resolved string into the request. The revised code places the supplied address into the request directly.
That difference changes what the cluster learns about the node. A request containing a numeric address describes the result of one resolution. A request containing a hostname describes an identifier that can be resolved later. Both can reach the same endpoint initially, but they behave differently after the endpoint moves.
The request still carries the node identifier and whether it is joining as a voter. Preserving the network name does not collapse those fields into one notion of identity. The membership operation needs a node identity, an address to contact, and a participation role. The patch changes the address representation while retaining that structure.
This makes the problem more specific than whether a startup command accepts a hostname. Earlier code could accept one successfully and still discard it before submitting the join. From the operator's perspective, the command appeared to use a stable name. From the cluster's perspective, it received an address tied to the current instance.
An advertised address need not be a resolved endpoint
The patch adds NameAddress, a small type that holds an address string and supplies Network and String methods. Its network method reports TCP, while its string method returns the supplied value. This lets the surrounding transport retain a name in an address-shaped interface without requiring eager resolution.
The distinction is useful because an advertised address communicates how peers should reach a node. It is not necessarily the same as a listener's local bind address. A process can listen on a local interface while advertising a name that other nodes can resolve and contact. Preserving that advertised name keeps configuration intent intact.
Single-node bootstrap also changes to use the configured advertised Raft address. That ensures the node's initial membership information uses the representation the operator supplied. The patch therefore addresses both joining an existing cluster and establishing an initial cluster entry.
The accompanying test creates a named address, checks that the network is TCP, and checks that its string remains the original hostname and port. It verifies the local representation contract introduced by the type. It does not by itself prove every behavior of DNS resolution or every platform's replacement lifecycle.
Local-request handling needs the same representation
The cluster client has an optimization for serving requests to its own local service without a network exchange. Before this change, setting the local address also resolved it. A comment explained that the client had to match the resolved representation used by Raft. The patch removes both the resolution and that assumption.
This is a small but relevant part of making the overall change coherent. Address representations appear in several places within a distributed process. If membership retains a hostname while a local lookup retains only its resolved IP, two parts of the program may fail to recognize the same configured endpoint. A networking change needs to account for those comparisons as well as dialing.
The revised client stores the supplied address directly. That aligns its local-service identifier with the hostname-preserving direction of the rest of the patch. The change is therefore visible in joining, bootstrap, transport address representation, and local-request handling.
These paths explain why resolving a name at one apparently convenient point can spread assumptions through a codebase. Once other components rely on the numeric representation, removing early resolution requires revisiting their matching behavior. The patch makes those relationships explicit.
Discovery and later connectivity solve different problems
The changelog also records the earlier 7.2.0 release, which added DNS and DNS SRV automatic clustering. Discovery can provide addresses for initially finding peers. Preserving a hostname concerns what a node retains after receiving configuration or participating in membership.
A system can discover a node successfully and later fail to reach its replacement if it stores only an obsolete numeric address. Conversely, retaining a hostname is useful only if the environment maintains that name's meaning. These are separate responsibilities, so the new networking behavior complements the discovery work without replacing it.
For an operator, the relevant configuration choice is whether the provided identifier should follow future address changes. An explicit IP says to use that numeric endpoint. A stable hostname allows the network layer to resolve the current endpoint for the name. Version 7.3.0 preserves that choice rather than normalizing both forms into an IP during startup.
This does not promise immediate recovery from every address change. Existing connections, network failures, and name-resolution behavior still belong to the runtime environment. The narrower implemented guarantee is that rqlite no longer discards configured hostnames through its own eager resolution in these paths.
Existing membership needs an upgrade decision
The tagged changelog describes upgrading an existing cluster by explicitly supplying the IP address of each node. That keeps the configured representation aligned with the addresses an earlier version had already retained. Another documented option is backup and restoration into a new cluster. The underlying issue is that preserving names in new code does not automatically transform every old membership record into its intended hostname.
That makes the change operationally significant even though its code is small. A cluster's existing address representation and a process's new configuration need to agree during transition. Replacing binaries and assuming that previously resolved addresses become names would overlook where the old state lives.
The changelog's restoration wording contains a reference to a new 8.0 cluster, while the actual tagged release is 7.3.0. Its release page and heading establish which version ships this behavior. For migration, the useful distinction remains retaining the previous numeric identities or creating new membership with the desired names.
Consider an illustrative node advertised as database-1.example:4002. Its name might initially resolve to one address and, after replacement, resolve to another. A join request carrying the first numeric address cannot express that the operator wanted the second address to become reachable through the same name. A join request retaining the name preserves that intent for later connections. The example does not require rqlite to operate DNS or decide which process should own the name. Those remain deployment responsibilities. It requires the database to avoid replacing the supplied identifier with information that is valid only at the moment of configuration. This is the behavior implemented by removing the explicit resolution calls in the patch.
I see this release as a correction to where resolution belongs. rqlite needs to retain the configured endpoint identity, and the networking implementation needs to turn it into a reachable connection. Keeping those steps separate lets a deployment update the address behind a stable name without asking rqlite to treat each new numeric address as the original configuration.
The practical effect is strongest in environments that deliberately separate service identity from process placement. A replacement process can use the same hostname and port while the environment updates its address. With hostname-preserving membership and join requests, the database keeps the identifier designed to survive that replacement. Explicit-IP deployments retain their existing model, while name-based deployments can use the indirection they supplied.