amir20/dozzle · error
invalid webhook URL scheme
Error message
invalid webhook URL scheme %q: only http and https are allowed
What it means
NewWebhookDispatcher only allows http and https schemes (checked case-insensitively after url.Parse succeeds). Any other scheme, including dangerous ones like file://, ftp://, or gopher://, is rejected with this error to prevent SSRF-style abuse and misconfiguration.
Solutions
- Prefix the URL with https:// (or http:// only for intentionally insecure internal targets)
- If the scheme is empty because the scheme was omitted, add it explicitly
- Use a standard HTTPS webhook endpoint from the target service's docs
Example fix
// before
NewWebhookDispatcher("hook", "example.com/webhook", "", nil)
// after
NewWebhookDispatcher("hook", "https://example.com/webhook", "", nil) Defensive patterns
Strategy: validation
Validate before calling
u, _ := url.Parse(rawURL)
if s := strings.ToLower(u.Scheme); s != "http" && s != "https" {
return errors.New("webhook URL must use http or https")
} Type guard
func isHTTPScheme(raw string) bool {
u, err := url.Parse(raw)
if err != nil { return false }
s := strings.ToLower(u.Scheme)
return s == "http" || s == "https"
} Try / catch
d, err := NewWebhookDispatcher(name, rawURL, tpl, headers)
if err != nil && strings.Contains(err.Error(), "scheme") {
// surface scheme requirement to the user
} Prevention
- Always include an explicit https:// prefix in stored webhook URLs
- Use a URL input field with scheme validation in configuration UIs
- Treat missing-scheme hostnames as invalid before saving
When it happens
Trigger: Calling NewWebhookDispatcher with a URL whose scheme is not http/https, e.g. "ftp://host/hook", "file:///tmp/x", or a URL with no scheme like "example.com/hook" (empty scheme).
Common situations: Users pasting a hostname without the https:// prefix; attempts to target local files or non-HTTP services; typo'd schemes (hxxp, webhooks://).
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
- invalid webhook URL
- webhook target resolves to a blocked address range
- failed to parse template
- Failed to save alert
- Toast id is required when once is true
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/16c507ac2de41aae.
Report an issue: GitHub.
Appendix: source
Thrown at internal/notification/dispatcher/webhook.go:168
// WebhookDispatcher sends notifications to a webhook URL
type WebhookDispatcher struct {
Name string
URL string
Template *template.Template
TemplateText string // Original template string for serialization
Headers map[string]string
client *http.Client
}
// NewWebhookDispatcher creates a new webhook dispatcher
// If templateStr is empty, the notification will be marshaled as JSON directly
func NewWebhookDispatcher(name, rawURL, templateStr string, headers map[string]string) (*WebhookDispatcher, error) {
parsed, err := url.Parse(rawURL)
if err != nil {
return nil, fmt.Errorf("invalid webhook URL: %w", err)
}
if scheme := strings.ToLower(parsed.Scheme); scheme != "http" && scheme != "https" {
return nil, fmt.Errorf("invalid webhook URL scheme %q: only http and https are allowed", parsed.Scheme)
}
w := &WebhookDispatcher{
Name: name,
URL: rawURL,
TemplateText: templateStr,
Headers: headers,
client: &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
DialContext: safeDialContext,
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
},
}
View on GitHub (pinned to d9463cbe21)