mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-12 17:59:06 +02:00
The bootstrap check keyed on GetClusterSupportsPrivate, which only looks at proxies heartbeating inside the 2-minute active window. That made the answer depend on timing rather than on the cluster: a centralised cluster was refused while its proxies were live, and the same cluster became pinnable once they had been quiet for two minutes, because an unreported capability was read as "nothing to judge". Waiting for a proxy to go quiet was a way to pin the account's immutable endpoint to a cluster that can never serve its gateway. Decide on the proxy rows instead. A cluster's rows outlive its proxies' liveness — only the hourly stale reaper removes them — so a cluster management has ever seen stays judged as one, and it must then prove it can serve the gateway with a live embedded proxy: both an explicit false and an unproven capability are refused, since the pin cannot be revisited later. Ownership comes from the same time-independent source, so a foreign BYOP cluster stays refused while it is offline too. Only a cluster no proxy has ever declared is still pinnable, which is the address-first order the dedicated path documents. The e2e test now walks one cluster address through all three states — live centralised, stopped, then embedded — so the middle one is covered against the real thing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>