rqlite accepts several explicit cluster join addresses
rqlite 3.13.0 lets a starting node try a comma-separated list of cluster contacts. It also makes CLI redirect handling explicit so the application retains control of leader forwarding.
A replicated database can survive a failed member while a new node still depends on one hard-coded address to join it. That leaves bootstrap less flexible than the running cluster. rqlite 3.13.0, released on 4 April, allows multiple explicit join addresses so a starting node can try another contact when the first does not accept its request.
The tagged changelog identifies pull request 294 as the change. The feature extends the existing ordered candidate list used by discovery. It does not introduce a separate membership protocol. Explicit configuration can now supply several candidates to the same join helper.
I value this because it removes an avoidable dependency from a small cluster's startup configuration. An operator who already knows several API endpoints should be able to give the node those endpoints. Requiring an external discovery service solely to express that list would add machinery without adding useful information.
One argument becomes a candidate list
The released startup code splits the -join argument at commas. The resulting strings become the initial candidate addresses. An invocation can therefore name two existing API endpoints in the same argument.
rqlited -join http://node-a:4001,http://node-b:4001 ~/node-new
This example assumes the named endpoints are reachable and the new node's other network settings suit the deployment. The argument names HTTP join contacts, rather than the Raft listener addresses. The join request separately carries the Raft address that the cluster will use for the new member.
The implementation uses a literal string split. It does not trim whitespace from each candidate in that function. Writing the list without spaces therefore matches what the parser actually expects. The order also matters because the helper tries candidates in sequence and returns after a successful join.
If discovery is configured too, its returned addresses follow the explicit list. The source comments call explicit addresses the first priority. A deployment can use known contacts first while still obtaining additional contacts from the registry. Both sources contribute to the same list.
Retrying a join is bounded
The 3.13.0 join helper walks all candidates during each pass. It attempts up to three passes, with a five-second wait after an unsuccessful pass. A successful join returns the endpoint used, giving startup a specific result to log.
This behavior supports a common startup condition. One endpoint may be unavailable while another member can handle or redirect the request. Giving the helper several addresses lets it use that alternative. The list does not need to predict which member is currently leader.
The helper explicitly processes leader redirects. It posts a JSON object containing the joining Raft address to /join. On a 301 response, it follows the Location value and posts the request again. An absent destination produces an error. Other unsuccessful statuses also produce an error with response information.
The candidate list improves contact availability, but it does not grant membership by itself. The remote join operation must still succeed. A list containing only unreachable or rejecting endpoints eventually fails rather than establishing an independent claim that the node joined the intended cluster.
I prefer that narrow interpretation because it gives the setting a clear job. Several addresses improve the chance of reaching a functioning join endpoint. Consensus and the actual membership operation continue to determine the database cluster that results.
The CLI also owns its redirects
The release fixes a related client issue through pull request 297. According to the changelog, the CLI must explicitly handle redirects because of Go 1.8. The client implementation now sets CheckRedirect to return http.ErrUseLastResponse.
That instruction leaves the redirect response with rqlite's own request loop. The loop can then read the leader destination and construct another POST using the serialized SQL body. Without explicit ownership, an HTTP library's automatic behavior can interfere with the application's redirect protocol before its code sees the response.
The existing limit of 21 leader redirects remains. Exceeding it returns a maximum-redirect error. Redirect handling therefore has a separate bound from the join helper's repeated candidate passes. They occur in different clients and address different stages of contacting the cluster.
Build context becomes visible
Version 3.13.0 also logs the Go version at startup. That is relevant context for a release containing an adjustment attributed to a Go HTTP-client behavior change. The startup log identifies the runtime version instead of requiring an operator to infer it from the version of Go installed elsewhere on the machine.
The changes improve how clients reach the correct cluster endpoint. A new member can try several configured contacts, and the interactive CLI explicitly retains its leader-redirect response. In both cases, rqlite keeps the request semantics in its own code while using HTTP to reach an existing member.