* [client] Keep the updater silent until management decides the mode The update manager started in download-only mode and every engine stop reset it there again, kicking the update loop with the cached latest version. On a managed peer this published a "New version available" notification on each disconnect, session expiry or logout, and once more in the window between daemon start and the first network map. Users under enforced updates then installed the release by hand. Replace the boolean with a three-state mode. The manager starts undecided and publishes nothing, from the fetcher or from NotifyUI, until the network map picks download-only or managed. A new connection lifecycle resets to undecided; disconnects leave the last decision untouched. A missing AutoUpdateSettings now means download-only instead of a no-op, and on platforms without an installer SetVersion falls back to download-only so they keep notifying. * [client] Address review findings on the updater mode split Route every mode transition through one locked helper so the staged managed version cannot outlive the decision that created it. Both download-only transitions kept pendingVersion, letting Install put on the old enforced release after management disabled updates or the platform fell back to download-only. The helper also bumps a generation counter. handleUpdate and NotifyUI copy the mode under the mutex but publish and install after releasing it, so a reset landing in that window could still emit an enforced notification. Both now recheck the generation right before the side effect and drop the stale work. Reset on every connection attempt instead of once per run: the backoff loop reconnects without re-entering run, and since disconnects no longer force download-only, a fetch in the disconnected gap republished the enforced notification before the new network map arrived. A missing AutoUpdateSettings now logs that it defaults to download-only rather than claiming auto-update is disabled, which contradicted the notifications that mode still emits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * [client] Reset the updater mode on engine stop Removing SetDownloadOnly from the engine teardown also dropped the reset of the forced-update flag. After netbird down the manager kept the last management directive, so a release published while the client was stopped could still trigger a forced install that management no longer asked for. The same window existed between an engine teardown and the next reconnect attempt, where ResetMode only ran at the start of the attempt. Reset the mode in stopLocked instead, so the updater stays silent from the moment the engine goes down until the first network map of the next connection decides the mode again. * [client] Name the force-reset test for the behavior it proves The silence after ResetMode follows from the undecided mode alone, and the closing SetVersion overwrites forceUpdate from its argument, so the test cannot observe whether the flag itself was cleared. Name it for the stale directive staying silent, which is what it asserts. * [client] Fall back to download-only on a malformed expected version * [client] Compare the full auto-update directive before skipping it * [client] Set the mock latest version under its lock in the updater tests --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Start using NetBird at netbird.io
See Documentation
Join our Slack channel or our Community forum
🚀 We are hiring! Join us at https://netbird.io/careers
🤖 NetBird Agent Network (Beta)
Identity-aware access control for AI agents — keyless access to LLM APIs and private resources over the encrypted NetBird tunnel. See
agent-network/or read the docs at netbird.ai.
NetBird combines a configuration-free peer-to-peer private network and a centralized access control system in a single platform, making it easy to create secure private networks for your organization or home.
Connect. NetBird creates a WireGuard-based overlay network that automatically connects your machines over an encrypted tunnel, leaving behind the hassle of opening ports, complex firewall rules, VPN gateways, and so forth.
Secure. NetBird enables secure remote access by applying granular access policies while allowing you to manage them intuitively from a single place. Works universally on any infrastructure.
https://github.com/user-attachments/assets/10cec749-bb56-4ab3-97af-4e38850108d2
Self-host NetBird (video)
Key features
Quickstart with NetBird Cloud
- Download and install NetBird at https://app.netbird.io/install.
- Follow the steps to sign up with Google, Microsoft, GitHub or your email address.
- Check the NetBird admin UI.
Quickstart with self-hosted NetBird
This is the quickest way to try self-hosted NetBird. It should take around 5 minutes to get started if you already have a public domain and a VM. Follow the Advanced guide with a custom identity provider for installations with different IdPs.
Infrastructure requirements:
- A Linux VM with at least 1 CPU and 2 GB of memory.
- The VM should be publicly accessible on TCP ports 80 and 443 and UDP port 3478.
- A public domain name pointing to the VM.
Software requirements:
- Docker with the Compose plugin (Compose v2 or higher). See the Docker installation guide.
Steps
- Download and run the installation script:
export NETBIRD_DOMAIN=netbird.example.com; curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash
A bit on NetBird internals
- Every machine in the network runs the NetBird agent, which manages WireGuard.
- Every agent connects to the Management Service, which holds network state, manages peer IPs, and distributes updates to agents.
- Agents use ICE (via pion/ice) to discover connection candidates for peer-to-peer connections.
- Candidates are discovered with the help of STUN servers.
- Agents negotiate a connection through the Signal Service, exchanging end-to-end encrypted messages with candidates.
- When NAT traversal fails (e.g. mobile carrier-grade NAT) and a direct p2p connection isn't possible, the system falls back to a Relay Service and a secure WireGuard tunnel is established through it.
See a complete architecture overview for details.
Reporting bugs and requesting features
NetBird uses a discussion-first workflow. Bug reports and feature requests start in Discussions, not as issues.
| What you want to do | Where to go |
|---|---|
| Report a bug, regression, or unexpected behavior | Issue Triage |
| Request a feature or share an idea | Ideas & Feature Requests |
| Ask about setup, configuration, or self-hosting | Q&A / Support |
| Report a security vulnerability | Security policy, never a public thread |
Our team and maintainers triage discussions, ask follow-up questions, check for duplicates, and reproduce bugs. Validated reports are promoted to issues. This keeps the issue tracker a clear answer to one question: what is the team working on.
Please search existing discussions and issues first, including closed ones. If something similar already exists, upvote it and add your details there instead of opening a duplicate.
For bug reports, include your NetBird version, operating system, deployment type (Cloud, self-hosted, Kubernetes, or Docker), reproduction steps, expected and actual behavior, and a debug bundle where relevant:
netbird version
netbird status -d -A
netbird debug for 1m -A -S -U
-U uploads the bundle and prints a file key you can paste instead of attaching the archive.
-A anonymizes the output, which matters on a public thread. It masks most identifying details
but is not full redaction, so read the bundle before posting it. Two levels are available:
| Level | How to select | What it masks |
|---|---|---|
default |
-A / --anonymize |
Public IP addresses, IPv6 ULA addresses, MAC addresses, and domains other than netbird.io, netbird.cloud, netbird.selfhosted, and netbird.stage. IPv4 private, CGNAT, and link-local ranges are kept |
strict |
--anonymize-level strict (implies -A) |
The above, plus IPv4 private, CGNAT, and link-local ranges, peer names in front of netbird.cloud, netbird.selfhosted, and netbird.stage, and WireGuard public keys. Labels under netbird.io are kept, since it only hosts infrastructure |
See collecting a debug bundle and the CLI reference for details.
See How to use Discussions, Issues, and Pull Requests for the full workflow, or SUPPORT.md for a shorter version.
Contributing
Contributions are welcome. Read CONTRIBUTING.md first. NetBird works ticket first, anything that changes behavior needs an issue the team has agreed on before you open a pull request.
Community projects
- NetBird installer script
- netbird-tui - terminal UI for managing NetBird peers, routes, and settings
- caddy-netbird - Caddy plugin that embeds a NetBird client for proxying HTTP and TCP/UDP traffic through NetBird networks
Note: The main branch may be in an unstable or even broken state during development.
For stable versions, see releases.
Support acknowledgement
In November 2022, NetBird joined the StartUpSecure program sponsored by the Federal Ministry of Education and Research of the Federal Republic of Germany. Together with the CISPA Helmholtz Center for Information Security, NetBird brings security best practices and simplicity to private networking.
Acknowledgements
We build on open source technologies like WireGuard®, Pion ICE, and Rosenpass. We greatly appreciate the work these projects are doing, and we'd love it if you could support them too (e.g., by starring or contributing).
Legal
This repository is licensed under the BSD-3-Clause license, which applies to all parts of the repository except for the directories management/, signal/ and relay/. Those directories are licensed under the GNU Affero General Public License version 3.0 (AGPLv3). See the respective LICENSE files inside each directory.
WireGuard and the WireGuard logo are registered trademarks of Jason A. Donenfeld.



