Skip to content

[P3] XDS versionCount resets to 1 on router restart — config changes may not reach Envoy #617

Closed

Description

Severity: P3 (edge case; only affects first restart after exactly one prior snapshot)
Component: Network Plane — cmd/atenet/internal/router/xds.go
Audit ID: NET-9


Summary

The XDS snapshot version counter is an in-memory int64 starting at 0. Each router
restart begins versioning at 1. If Envoy previously ACKed snapshot version "1" and
the router restarts pushing a new config as version "1" again (same string), the
go-control-plane ADS server may not re-push the config (depending on its same-version
handling). This creates a small window where Envoy's config reflects the pre-restart
state rather than the new state.


Root Cause

File: cmd/atenet/internal/router/xds.go lines 99–100

var versionCount int64 = 0  // reset to 0 on every process start

func nextVersion() string {
    return strconv.FormatInt(atomic.AddInt64(&versionCount, 1), 10)
    // First call after restart always returns "1"
}

The go-control-plane cache's behavior when a client reconnects with version_info="1"
and the server's current version is also "1" depends on the implementation:
if the cache treats it as "client already has this version," it may not push an update.


Steps to Reproduce

# Initial state: router running, Envoy has ACKed version "1" (just started)
# Confirm via Envoy admin
curl http://localhost:9901/config_dump | jq '.configs[] | select(.["@type"] | contains("ScopedRoutesConfig")) | .version_info'
# "1"

# Change router config and restart
kubectl set env -n ate-system deployment/atenet-router SOME_PARAM=new_value
kubectl rollout restart -n ate-system deployment/atenet-router

# New router pushes version "1" again (reset counter)
# Envoy may not receive the updated config if it reconnects and sends version_info="1"
curl http://localhost:9901/config_dump | jq '...'
# May still show old config

Suggested Fix

Initialize versionCount with a monotonically increasing base that survives restarts:

// Use Unix timestamp as base to ensure monotonic increase across restarts
var versionCount int64 = time.Now().Unix()

Or use a UUID-based version string that is always different from any prior version,
eliminating the same-version collision entirely:

func nextVersion() string {
    return fmt.Sprintf("%d-%d", startupTimestamp, atomic.AddInt64(&versionCount, 1))
}

Activity

  1. changed the title [-]XDS versionCount resets to 1 on router restart — config changes may not reach Envoy[/-] [+][P3] XDS versionCount resets to 1 on router restart — config changes may not reach Envoy[/+] on Jul 30, 2026
  2. added 14 commits that reference this issue on Aug 4, 2026
    1737b7c
    709fd68
    d81869f
    ac7571d
    bea2dd5
    a8aa1cd
    0cf3bc5
    cf05382
    d7cf902
    0ca6732
    3bdb242
    3bb0f4a
    defea90
    d1e72ef
  3. added a commit that references this issue on Aug 19, 2026
    f50a632
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/networkkind/bugSomething isn't working / bugfixesprio/P2real, but not urgent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions