<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Fixes#46643
BaseClient.URL() built request paths as `URLPrefix + path`, overwriting
any path already present in BaseURL. Orbit and Fleet Desktop parse the
full fleet URL (subpath included) into BaseURL and pass an empty
URLPrefix, so the subpath was discarded and every API call 404'd when
Fleet was deployed at https://host/subpath. Preserve BaseURL.Path as a
prefix on each request. fleetctl is unaffected since it carries the
subpath in URLPrefix with an empty BaseURL.Path, and non-subpath
deployments are unchanged.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] Verified that fleetd runs on macOS, Linux and Windows
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed API request URL construction for deployments hosted under a
subpath, preventing broken requests and 404 errors.
* Preserved query parameters when generating request URLs.
* Improved resolution of request paths with and without a leading slash
when combined with a base URL subpath.
* **Documentation**
* Added clearer guidance on how base URL subpaths and additional path
prefixes are combined.
* **Tests**
* Expanded URL-generation coverage to verify correct behavior across
subpath and prefix combinations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes#45627
Part 2 of #45553 -- see there for the full behavioral contract and
Oracle.
## Changes
- Integrated the shared `orbit/pkg/backoff` package (shipped in #45624)
into orbit's `ExecuteConfigReceivers` loop
- On error (5xx, network failure): polling interval doubles each failure
(30s, 60s, 120s, ...) capped at 5 minutes
- On success: resets immediately to normal 30s polling
- The inner `retry.Do` in `GetConfig` (transient retry within a single
tick) is unchanged
## Manual testing
### Automated tests
```
go test ./orbit/pkg/backoff/ -race -count=1 # 17 tests, 0 failures
go test ./client/ -count=1 -short # client tests pass
```
### Build verification
```
go build ./orbit/cmd/orbit/ # compiles clean
go build ./orbit/cmd/desktop/ # compiles clean
```
### Dev environment testing
Built orbit from this branch and swapped it into a local dev setup
(`/opt/orbit/bin/orbit/macos/stable/orbit`). Server-side logs confirmed
that after the restart with the new binary, `/api/fleet/orbit/config`
requests stopped arriving at the fixed 30s cadence (old behavior),
consistent with backoff engaging on error responses. The `device_token`
endpoint (not covered by this PR) continued at its normal interval,
confirming the backoff is scoped to the config polling loop only.
Full end-to-end verification of the log messages (`backing off`,
`next_retry`, `exiting backoff`) should be done by QA with `sudo tail -f
/var/log/orbit/orbit.stderr.log`.
### QA manual test plan (cc @xpkoala)
**Setup:** Local Fleet server + orbit built from this branch (see build
steps above). Orbit logs are at `/var/log/orbit/orbit.stderr.log`
(requires `sudo`).
**Test 1 -- Backoff on server failure:**
1. Start Fleet server, verify orbit connects (config requests every ~30s
in server log)
2. Stop the Fleet server (`kill` the process or `docker stop` the
container)
3. Watch orbit logs: `sudo tail -f /var/log/orbit/orbit.stderr.log`
4. **Expected:** Log lines with `"running config receivers, backing
off"` and `next_retry` values increasing: ~60s, ~120s, ~240s, then
capping at ~5m (values include up to 10% random jitter)
**Test 2 -- Recovery resets to normal:**
1. While orbit is in backoff (from Test 1), restart the Fleet server
2. Wait for the next backoff tick to fire
3. **Expected:** Log line `"config receivers succeeded, exiting
backoff"` with `backoff_duration` showing how long the backoff lasted,
then polling resumes at normal 30s
**Test 3 -- Normal operation unchanged:**
1. With both server and orbit running healthy, watch orbit logs for ~2
minutes
2. **Expected:** No backoff-related log lines. Config polling stays at
30s intervals.
---
# Checklist for submitter
- [x] Changes file added for user-visible changes in `orbit/changes/`.
- [x] Input data is properly validated, no SQL changes, no JS changes.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops (backoff caps at 5 min).
- [x] Added/updated automated tests (existing backoff package tests
cover the mechanism).
- [ ] QA'd all new/changed functionality manually.
## fleetd/orbit/Fleet Desktop
- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes (backoff is
platform-agnostic).
- [ ] Verified that fleetd runs on macOS, Linux and Windows.
- [ ] Verified auto-update works from the released version of component
to the new version.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Config polling now implements exponential backoff on network/server
failures, gradually increasing retry intervals up to a 5-minute maximum
instead of fixed intervals.
* After a successful config poll, the retry schedule automatically
resets back to the normal update interval.
* **Tests**
* Added unit tests to verify backoff increases after repeated failures
and resets promptly after recovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#47650
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [x] Verified that fleetd runs on macOS, Linux and Windows
- [x] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **Bug Fixes**
* Improved authentication resilience by debouncing repeated unauthorized
responses and only triggering recovery after a grace period.
* Updated node-key handling to avoid treating empty key files as valid
and to prevent accidental deletion during short failures.
* Ensured node-key storage is written atomically to avoid partial or
empty credential files.
* **Tests**
* Added comprehensive test coverage for node re-enrollment behavior,
authentication grace-period timing, and atomic file write guarantees.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#41379
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [ ] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [ ] Verified that fleetd runs on macOS, Linux and Windows
- [ ] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added EUA token support to Orbit enrollment workflow
* Introduced `--eua-token` CLI flag for Windows MDM enrollment
* Windows MSI packages now support EUA_TOKEN property (Orbit v1.55.0+)
* **Tests**
* Added tests for EUA token handling in enrollment and Windows packaging
* **Documentation**
* Added changelog entry documenting EUA token inclusion in enrollment
requests
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Resolves#40396.
No changes file because there should be no user visible changes.
## Testing
- [x] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [X] Verified that fleetd runs on macOS, Linux and Windows
- [X] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))