Kuberwastaken/claurst · error · anyhow::Error

No authentication available for remote settings

Error message

No authentication available for remote settings

What it means

RemoteSettings::fetch_once requires auth headers for the settings endpoint; when auth_headers() returns None it fails instead of making an anonymous request. Remote settings are gated behind authentication, so no credentials means no fetch. fetch_with_retry propagates this as a permanent failure.

Solutions

  1. Complete the authentication flow so the auth store has valid credentials.
  2. Skip remote-settings fetch when unauthenticated (treat as a no-op rather than an error).
  3. Set the required token env var / config if the auth store supports it.

Example fix

// before
settings.fetch_with_retry().await?;
// after
if settings.auth_headers().is_some() {
    let _ = settings.fetch_with_retry().await; // or map Err to a warning
} // else: keep cached settings
Defensive patterns

Strategy: fallback

Try / catch

match settings.fetch_with_retry().await {
    Ok(Some(s)) => apply(s),
    Ok(None) | Err(_) => apply_cached(), // 304 or unauthenticated: keep cache
}

Prevention

When it happens

Trigger: Calling fetch_with_retry/fetch_once when the user has no stored credentials (fresh install, logged out, or auth store empty) and the remote settings endpoint requires authentication.

Common situations: Running before first login/OAuth flow; credentials expired and were cleared; CI environment without an auth token; auth store file missing or unreadable.

Understand the failure class

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/d7b41c5a6374278f. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/core/src/remote_settings.rs:196

        tokio::fs::write(&self.cache_path, text).await?;
        Ok(())
    }

    /// Delete the on-disk cache file.
    pub async fn clear_cache(&self) {
        let _ = tokio::fs::remove_file(&self.cache_path).await;
    }

    /// Perform a single fetch attempt (no retries).
    ///
    /// Returns:
    /// - `Ok(Some(settings))` — new settings fetched
    /// - `Ok(None)` — 304 Not Modified; caller should keep cached value
    /// - `Err(...)` — transient or permanent failure
    async fn fetch_once(&self, cached_checksum: Option<&str>) -> Result<Option<Value>> {
        let auth = self
            .auth_headers()
            .ok_or_else(|| anyhow::anyhow!("No authentication available for remote settings"))?;

        let mut req = self.http.get(self.endpoint());
        for (k, v) in &auth {
            req = req.header(k.as_str(), v.as_str());
        }
        if let Some(cs) = cached_checksum {
            req = req.header("If-None-Match", format!("\"{}\"", cs));
        }

        let resp = req.send().await?;
        let status = resp.status().as_u16();

        match status {
            304 => {
                debug!("Remote settings: 304 Not Modified — cache still valid");
                return Ok(None);
            }
            204 | 404 => {

View on GitHub (pinned to b0637c97ec)