Skip to content

Granola Windows FMA repeatedly breaks GitOps runs as vendor rotates installer URLsΒ #45359

@kc9wwh

Description

@kc9wwh

Fleet versions

  • Discovered: v4.83.0
  • Reproduced: v4.83.2

Web browser and operating system: N/A


πŸ’₯ Actual behavior

fleetctl gitops fails with a fatal validation error when the Granola Windows FMA (slug: granola/windows) is present in software config. The dry-run aborts even when the user's change has nothing to do with Granola or Windows.

Representative error:

Error: applying software installers for fleet "πŸ’» Windows": validation failed: software.url Couldn't edit software. URL ("https://api.granola.ai/v1/check-for-update/Granola-7.162.2-win-x64.exe") received response status code 403.
Error: Process completed with exit code 1.

Root cause appears to be vendor-side URL invalidation cadence: Granola ships new Windows versions every few days and invalidates the previous version's installer URL (returns 403) as soon as the new release goes out. Fleet refreshes the FMA catalog 6 times a day, but the Granola invalidation window is short enough that a customer's GitOps run can still land on a URL that's already dead between catalog refreshes. The run then fails fatally rather than warning.

Observed on three separate occasions over the span of three weeks, each tied to a new Granola release. Independently reproduced by a Fleet engineer.

πŸ› οΈ Expected behavior

The customer's expectation is simple: GitOps should just work. Fleet should grab the latest valid installer URL at run time without failing because the vendor rotated a version-specific URL.

Possible directions:

  • Stable "latest" URL fallback: Point the Granola FMA entry at a vendor-provided, version-agnostic URL (e.g., https://api.granola.ai/v1/download-latest-windows) that always resolves to the current installer. Fleet resolves the actual version at run time rather than validating against a pinned URL that may already be dead. Could be generalized to any FMA whose vendor offers a stable "latest" endpoint.
  • Resolve-at-run for FMAs: Refetch the FMA installer URL from the catalog at GitOps execution time rather than validating against a snapshot that may have gone stale between catalog refreshes.
  • Skip re-validation when unchanged: If the FMA slug hasn't changed since the last successful run, skip the URL validation step for that entry.

PD to specify final behavior.

πŸ§‘β€πŸ’» Steps to reproduce

These steps:

  • Have been confirmed to consistently lead to reproduction in multiple Fleet instances.
  • Describe the workflow that led to the error, but have not yet been reproduced in multiple Fleet instances.
  1. Add slug: granola/windows to a Windows team's software.packages in a GitOps repo.
  2. Successfully run fleetctl gitops once to confirm the baseline works.
  3. Wait until the next Granola release ships (typically within a few days).
  4. Make any unrelated change in the GitOps config and run fleetctl gitops (or fleetctl gitops --dry-run) again.
  5. Observe: the run fails with software.url ... received response status code 403 pointing at the previous Granola Windows installer URL.

πŸ•―οΈ More info (optional)

  • Workaround: Comment out the granola/windows slug, re-run GitOps to unblock, then add it back once Fleet's next FMA catalog refresh has picked up the latest valid URL. Not sustainable given the recurrence rate.
  • Cross-issue context: Related FMA version staleness behavior was filed as Granola FMA entry displays older version than Fleet reports as latestΒ #44062. This issue is distinct β€” it's about GitOps fatally failing rather than displaying a stale version.
  • Vendor behavior: Granola appears to invalidate old version URLs immediately on release rather than preserving them or returning a stable redirect. The customer has reached out to Granola directly and received a response acknowledging the issue; no commitment on URL stability yet.
  • Business impact: Frequent enough that the team has discussed internally whether Granola is viable as an FMA at all in its current form.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions