Hmbown/CodeWhale · error
fleet alert URL from
Error message
fleet alert URL from {name} must use https What it means
required_https_url() validates every Webhook alert URL with reqwest::Url::parse and then rejects any scheme other than https. This is a deliberate hardening step so alert payloads (which include run ids, status, and failure reasons) are never sent over plaintext HTTP where they could be read or tampered with. The error names the env var the URL came from.
Solutions
- Change the env var's value to an https:// URL (put a TLS terminator in front of local test receivers, e.g. an ngrok/local reverse proxy).
- Double-check the scheme spelling and that the value parses as an absolute URL — 'example.com/hook' without a scheme fails earlier with the not-a-valid-URL context error.
- For local testing keep dry_run=true, which validates config shape without sending.
- If you must target plain HTTP internally, that is intentionally unsupported — file the alert through a different mechanism rather than weakening the check.
Example fix
# before $ export ALERT_HOOK_URL="http://127.0.0.1:9000/fleet" # -> must use https # after $ export ALERT_HOOK_URL="https://hooks.internal.example.com/fleet"
Defensive patterns
Strategy: validation
Validate before calling
fn webhook_urls_are_https(cfg: &FleetAlertConfig) -> Result<(), String> {
for (name, adapter) in &cfg.adapters {
if let FleetAlertAdapterConfig::Webhook { url_env, .. } = adapter {
if let Ok(url) = std::env::var(url_env) {
if reqwest::Url::parse(&url).map(|u| u.scheme() != "https").unwrap_or(true) {
return Err(format!("adapter '{name}': {url_env} must be an https:// URL"));
}
}
}
}
Ok(())
}
Type guard
fn is_https_url(s: &str) -> bool {
reqwest::Url::parse(s).map(|u| u.scheme() == "https").unwrap_or(false)
}
Try / catch
Err(e) if e.to_string().contains("must use https") => {
// value of the named env var is http:// — fix the env var; do not catch-and-send-over-http
}
Prevention
- Never point alert webhooks at http:// endpoints; front local receivers with TLS.
- Validate url_env values with Url::parse at deploy time, not at first alert.
- Watch for scheme-less values like 'hooks.example.com/x' — they fail earlier as invalid URLs.
- Include the https requirement in the runbook next to each *_env variable.
When it happens
Trigger: Setting the Webhook adapter's url_env to an http:// URL (e.g. a local test listener like http://127.0.0.1:9000/hook) and dispatching with dry_run=false; also URLs whose scheme parses oddly (e.g. 'localhost:8080/x' parses scheme 'localhost').
Common situations: Pointing alerts at a local dev receiver over plain HTTP; copying an internal http endpoint from docs; env vars provisioned by platforms that hand out http URLs by default; typos like missing '//' after https: are caught by the earlier parse error instead.
Related errors
- Fleet alert URL from
- fleet alert URL is not configured
- bundle URLs may not include credentials
- fleet alert adapter is not configured
- Fleet alert adapter is not configured
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/aab209b97c6be56a.
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 0c42157ee5)