Hmbown/CodeWhale · error

Fleet alert URL from

Error message

Fleet alert URL from {name} must use https

What it means

After resolving a Fleet alert URL, `validate_https_alert_url` parses it and requires the scheme to be exactly https. Plain http URLs are rejected because alert payloads may contain sensitive operational data and must not traverse unencrypted connections.

Solutions

  1. Change the URL secret to an https:// endpoint.
  2. If the target is internal-only, put it behind an https-terminating proxy or tunnel and use that https URL.
  3. For local testing, generate a local https cert or use an https tunnel instead of http.

Example fix

// before
export FLEET_WEBHOOK_URL=http://hooks.internal.example.com/alert
// after
export FLEET_WEBHOOK_URL=https://hooks.internal.example.com/alert
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_https(name: &str, url: &str) -> Result<()> {
    let parsed = reqwest::Url::parse(url)?;
    anyhow::ensure!(parsed.scheme() == "https", "{name} must be https");
    Ok(())
}

Try / catch

match send_alert(adapter, &prepared).await {
    Err(e) if e.to_string().contains("must use https") => {
        log::error!("refusing to send alert over insecure endpoint: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Configuring an alert endpoint secret with an `http://` (or other non-https) scheme and then sending an alert through the affected adapter.

Common situations: Pasting a local development webhook (http://localhost:...) into production config; an internal service still exposed over http; a proxy URL written without https.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c024eb4d64138ffa. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/fleet/alerts.rs:507

        .ok_or_else(|| anyhow!("Fleet alert secret {name} is not configured"))
}

fn required_https_url<R>(resolver: &R, name: &str) -> Result<String>
where
    R: FleetAlertSecretResolver,
{
    let url = resolver
        .resolve(name)
        .ok_or_else(|| anyhow!("Fleet alert URL {name} is not configured"))?;
    validate_https_alert_url(name, &url)?;
    Ok(url)
}

fn validate_https_alert_url(name: &str, url: &str) -> Result<()> {
    let parsed = reqwest::Url::parse(url)
        .with_context(|| format!("Fleet alert URL from {name} is not a valid URL"))?;
    if parsed.scheme() != "https" {
        return Err(anyhow!("Fleet alert URL from {name} must use https"));
    }
    Ok(())
}

fn short_reason(reason: &str) -> String {
    let trimmed = reason.trim();
    if trimmed.len() <= 240 {
        return trimmed.to_string();
    }
    let prefix: String = trimmed.chars().take(237).collect();
    format!("{prefix}...")
}

fn default_pagerduty_severity() -> String {
    "error".to_string()
}

#[cfg(test)]

View on GitHub (pinned to 73e0f67d83)