Skip to content

Sync listener address is hardcoded (0.0.0.0:9090); bind failure is non-fatal so a second instance runs silently without sync #209

Description

@emanzx

Summary

The sync WebSocket listener address is hardcoded to SyncListenerConfig::default() = 0.0.0.0:9090 — no config key, no env override. Combined with the bind failure being non-fatal, a second NodeDB instance on the same host starts cleanly, logs one WARN, and runs silently without sync.

Worse: because the first instance holds 0.0.0.0:9090, any client (or readiness probe) pointed at 127.0.0.1:9090 for the second instance silently connects to the first instance instead — a test/staging replica can end up syncing into production.

Environment

nodedb v0.4.0 (tag 38bfc3084). Every other listener (pgwire/native/http) is configurable via [server.ports]; sync is the only one that isn't.

Mechanism

  • nodedb/src/bootstrap/listeners.rs:152 — let sync_config = SyncListenerConfig::default(); (nothing read from ServerConfig)
  • nodedb/src/control/server/sync/listener.rs:34 — default 0.0.0.0:9090
  • bootstrap/listeners.rs — bind failure logs sync listener failed to start (non-fatal) and boot continues

Observed live: a 0.4.0 test instance coexisting with a production instance ran for two days sync-less with only the one WARN line to show for it; TCP probes on 127.0.0.1:9090 kept "succeeding" against the wrong instance.

Suggested fix

Read the sync listen address from config like every other listener (e.g. [server.ports] sync = 9090 or a [sync] listen_addr), and consider making bind failure fatal-by-default (or at least surfaced in readiness), since a sync-Origin that cannot accept sync is usually misconfigured rather than degraded.

Minimal interim patch we're running locally (env override, mirrors the pre-0.4.0 behavior our tooling relied on):

// bootstrap/listeners.rs
let mut sync_config = crate::control::server::sync::listener::SyncListenerConfig::default();
if let Ok(addr) = std::env::var("NODEDB_SYNC_LISTEN_ADDR") {
    match addr.parse() {
        Ok(parsed) => sync_config.listen_addr = parsed,
        Err(e) => tracing::warn!(error = %e, addr = %addr,
            "invalid NODEDB_SYNC_LISTEN_ADDR; keeping default sync listen address"),
    }
}

Happy to PR either shape (config key preferred) after triage.

Activity

  1. emanzx commented on Jul 22, 2026

    @emanzx
    ContributorAuthor

    Triage proposal (no label rights): type:bug sev:3-medium area:crdt-sync — operational with a workaround (the env-override patch in the report). Happy to PR the config-key shape after triage.

  2. added
    type:bugA defect — broken, incorrect, or lost data
    sev:3-mediumFeature wrong, but operational and a workaround exists
    on Jul 22, 2026
  3. emanzx commented on Jul 22, 2026

    @emanzx
    ContributorAuthor

    Verified present on origin/main @ 81169d3c7: bootstrap/listeners.rs:152 still constructs SyncListenerConfig::default() with nothing read from ServerConfig. Practical note: every verification run for #207/#208 today required the env-override patch from this report just to coexist with the production instance on one box — the need is real. Config-key PR offer stands post-triage.

  4. added a commit that references this issue on Jul 26, 2026
    9758058
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:crdt-syncCRDT, edge-to-cloud syncsev:3-mediumFeature wrong, but operational and a workaround existstype:bugA defect — broken, incorrect, or lost data

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions