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

  1. Prefer SendTest during setup to get the detailed TestResult (Error field, status, response body)
  2. Unwrap result.Error / the returned message to see the underlying cause (DNS, timeout, status code)
  3. Verify the endpoint is reachable from the Dozzle container and returns 2xx for the payload
  4. 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

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


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)