amir20/dozzle · error
webhook notification failed
Error message
webhook notification failed: %s
What it means
WebhookDispatcher.Send delegates to SendTest and converts a failed TestResult into a plain error, discarding the structured result. Any failure inside SendTest (template execution, HTTP request error, non-2xx response, refused private/loopback target, oversized reflection) surfaces here with this message.
Solutions
- Prefer SendTest during setup to get the detailed TestResult (Error field, status, response body)
- Unwrap result.Error / the returned message to see the underlying cause (DNS, timeout, status code)
- Verify the endpoint is reachable from the Dozzle container and returns 2xx for the payload
- Check SSRF guards: loopback and link-local targets are refused by design
Example fix
// before
err := w.Send(ctx, n) // loses detail
// after
res := w.SendTest(ctx, n)
if !res.Success {
log.Error().Str("detail", res.Error).Msg("webhook failed")
} Defensive patterns
Strategy: try-catch
Validate before calling
res := w.SendTest(ctx, testNotification)
if !res.Success {
return errors.New(res.Error)
} Try / catch
if err := w.Send(ctx, n); err != nil {
// log err; use SendTest in diagnostics for the structured cause
} Prevention
- Use SendTest with a test notification when configuring a webhook
- Confirm the endpoint returns 2xx for the rendered payload
- Remember Send drops detail; handle SendTest results for observability
When it happens
Trigger: Calling WebhookDispatcher.Send when the target URL is unreachable, returns a non-2xx status, the rendered payload fails, or SendTest's SSRF guards reject the target.
Common situations: Webhook receiver down or moved; firewall blocking outbound calls from the Dozzle container; receiver returning 500 on the payload; misconfigured headers/auth on the endpoint.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to save destination
- Failed to save alert
- Preview failed
- cloud search failed
- (await res.json().catch(() =>
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/08b48efc3d4f82d3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/notification/dispatcher/webhook.go:209
}
w.Template = tmpl
}
return w, nil
}
// TestResult contains the result of a webhook test
type TestResult struct {
Success bool
StatusCode int
Error string
}
// Send sends a notification to the webhook URL
func (w *WebhookDispatcher) Send(ctx context.Context, notification types.Notification) error {
result := w.SendTest(ctx, notification)
if !result.Success {
return fmt.Errorf("webhook notification failed: %s", result.Error)
}
return nil
}
// SendTest sends a notification and returns detailed result for testing
func (w *WebhookDispatcher) SendTest(ctx context.Context, notification types.Notification) TestResult {
var payload []byte
var err error
if w.Template != nil {
payload, err = executeJSONTemplate(w.TemplateText, notification)
if err != nil {
return TestResult{Success: false, Error: fmt.Sprintf("failed to execute template: %v", err)}
}
} else {
payload, err = json.Marshal(notification)
if err != nil {
return TestResult{Success: false, Error: fmt.Sprintf("failed to marshal notification: %v", err)}View on GitHub (pinned to d9463cbe21)