Skip to content

fix: retry on first connection failure and on failed IRC registration#413

Open
mbologna wants to merge 1 commit intokiwiirc:masterfrom
mbologna:fix/reconnect-attempts-initial-value
Open

fix: retry on first connection failure and on failed IRC registration#413
mbologna wants to merge 1 commit intokiwiirc:masterfrom
mbologna:fix/reconnect-attempts-initial-value

Conversation

@mbologna
Copy link
Copy Markdown

Problem

When an IRC connection fails for the first time (DNS not yet ready, transient network error, ECONNRESET during registration), The Lounge shows:

Disconnected from the network, and will not reconnect. Use /connect to reconnect again.

Even though auto_reconnect is enabled and auto_reconnect_max_retries is set to a high value (e.g. 30 in The Lounge). This has been reported in several places:

Root cause

The reconnect decision in socketClose is:

} else if (that.reconnect_attempts && that.reconnect_attempts < that.auto_reconnect_max_retries) {
    should_reconnect = true;

// If we were originally connected OK, reconnect
} else if (was_connected && safely_registered) {
    should_reconnect = true;
} else {
    should_reconnect = false;
}

Bug 1 — initial value: reconnect_attempts is initialised to 0. Since 0 is falsy in JavaScript, the first branch never fires on a first-ever connection failure. was_connected is also false, so the second branch doesn't fire either. Result: the very first failure gives up immediately, no matter how high max_retries is.

Bug 2 — premature reset: reconnect_attempts is reset to 0 inside socketOpen (raw TCP connect). This means a connection that reached the TCP layer but failed IRC registration (auth timeout, server-side ECONNRESET during NICK/USER, netsplit during connect) will reset the counter on the next attempt's TCP connect, effectively giving only one IRC-level retry before exhausting the counter.

Both bugs can be observed in the log pattern from #4103:

Reconnecting in 11 seconds… (Attempt 4)   ← TCP connects
Connected to the network.                  ← socketOpen fires, resets counter to 0
-server- *** Found your hostname
Connection closed unexpectedly: ECONNRESET ← socketClose fires, reconnect_attempts == 0 → give up
Disconnected from the network, and will not reconnect.

Fix

Three minimal changes, first proposed by @mornfall in this issue:

  1. Initialise reconnect_attempts to 1 — the first failure now satisfies reconnect_attempts > 0 && reconnect_attempts < max_retries, triggering a retry.

  2. Remove the reset from socketOpen — a raw TCP connection is not a successful IRC session. The counter should not reset until IRC registration completes.

  3. Reset to 1 in registeredSuccessfully — after a fully successful registration, the counter resets so the next connection problem gets a fresh set of retries.

Validation

@mornfall has been running this exact fix in production for 2+ years with ~100 users without issues (last comment in this thread). The fix has also been independently validated by @tokariu.

Diff

-        this.reconnect_attempts = 0;
+        this.reconnect_attempts = 1;

     registeredSuccessfully() {
         this.registered = Date.now();
+        this.reconnect_attempts = 1;
     }

     function socketOpen() {
         that.debugOut('Socket fully connected');
-        that.reconnect_attempts = 0;
         that.connected = true;

Root cause: the socketClose reconnect gate checks
  reconnect_attempts > 0 && reconnect_attempts < max_retries

But reconnect_attempts is initialised to 0, so the first connection
failure always falls through to "give up" — the condition is falsy.

Additionally, reconnect_attempts is reset in socketOpen (raw TCP
connect), not in registeredSuccessfully. A connection that got a TCP
socket but failed IRC registration (auth timeout, ECONNRESET during
registration, server-side kill) would reset the counter immediately on
the next attempt, exhausting retries before IRC registration ever
succeeds.

Fix (proposed by mornfall in kiwiirc#211, validated with ~100 users for 2+
years without issues):

1. Initialise reconnect_attempts to 1 so the first failure triggers the
   retry branch.
2. Remove the premature reset from socketOpen (TCP connected ≠ IRC
   registered).
3. Reset reconnect_attempts to 1 in registeredSuccessfully so the
   counter starts fresh after a fully successful registration.

Fixes kiwiirc#211
@tokariu
Copy link
Copy Markdown

tokariu commented Apr 25, 2026

I've been running this fix on my instance for years now without issues and the handling of reconnects is much better this way. it's like it should've been from the beginning. so let's add it then.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants