A webhook that answers with a redirect is counted as a successful delivery #287

Closed
opened 2026-10-13 22:55:40 +02:00 by clawbot · 2 comments
Collaborator

What is wrong. A delivery counts as failed only when the request errors or the reply's status is 400 or more. A 3xx reply counts as delivered: the request goes through RoundTrip, not a client, so the redirect is not followed, nothing is retried, nothing is logged, and the notification never reaches that endpoint. The dashboard's Recent alerts show it as sent.

Where (at v1.0.0-rc1): internal/notify/notify.go, sendSlack lines 426-431 and sendNtfy lines 336-341, both resp.StatusCode >= httpStatusClientError with httpStatusClientError = 400 (line 29).

Scenario. DNSWATCHER_MATTERMOST_WEBHOOK=http://mattermost.example.net/hooks/xxx, where the server redirects plain HTTP to HTTPS: every POST gets 301 Moved Permanently, every delivery is counted as a success, and no notification ever arrives, with nothing in the log to say so. The same holds for a 302 or 307 from a proxy in front of any of the three endpoints. Confirmed by reading; not reproduced against a real endpoint.

Correct. README, Notifications: "A delivery that fails (a network error, no reply within 10 seconds, or an HTTP status of 400 or more) is retried". Only a 2xx reply means the endpoint accepted the notification. My reading: a reply with a status outside 2xx is a failed delivery, retried and logged as the others are, and the README says "a status other than 2xx".

Done when: a 3xx reply is a failed delivery; a notify test with a test server answering 302 sees the retries and the final failed to send notification after retries log line; the README's Notifications paragraph says which statuses fail.

Severity: minor

Model: fable-5-1

**What is wrong.** A delivery counts as failed only when the request errors or the reply's status is 400 or more. A 3xx reply counts as delivered: the request goes through `RoundTrip`, not a client, so the redirect is not followed, nothing is retried, nothing is logged, and the notification never reaches that endpoint. The dashboard's Recent alerts show it as sent. **Where** (at `v1.0.0-rc1`): `internal/notify/notify.go`, `sendSlack` lines 426-431 and `sendNtfy` lines 336-341, both `resp.StatusCode >= httpStatusClientError` with `httpStatusClientError = 400` (line 29). **Scenario.** `DNSWATCHER_MATTERMOST_WEBHOOK=http://mattermost.example.net/hooks/xxx`, where the server redirects plain HTTP to HTTPS: every POST gets `301 Moved Permanently`, every delivery is counted as a success, and no notification ever arrives, with nothing in the log to say so. The same holds for a `302` or `307` from a proxy in front of any of the three endpoints. Confirmed by reading; not reproduced against a real endpoint. **Correct.** README, Notifications: "A delivery that fails (a network error, no reply within 10 seconds, or an HTTP status of 400 or more) is retried". Only a 2xx reply means the endpoint accepted the notification. My reading: a reply with a status outside 2xx is a failed delivery, retried and logged as the others are, and the README says "a status other than 2xx". **Done when:** a 3xx reply is a failed delivery; a notify test with a test server answering `302` sees the retries and the final `failed to send notification after retries` log line; the README's Notifications paragraph says which statuses fail. Severity: minor Model: fable-5-1
clawbot self-assigned this 2026-10-13 22:55:41 +02:00
Author
Collaborator

Plan. Package internal/notify; no new package. Runs after #288, which changes the same functions. In sendNtfy and sendSlack a reply whose status is outside 200-299 is a failed delivery, retried and logged as the others are; the constant that names 400 goes. Notify test: a test server answering 302 sees every retry and the final failed to send notification after retries line. README, Notifications: "an HTTP status other than 2xx". TODO.md Completed Steps entry in the same commit.

Model: opus-5-5

Plan. Package `internal/notify`; no new package. Runs after https://git.eeqj.de/sneak/dnswatcher/issues/288, which changes the same functions. In `sendNtfy` and `sendSlack` a reply whose status is outside 200-299 is a failed delivery, retried and logged as the others are; the constant that names 400 goes. Notify test: a test server answering `302` sees every retry and the final `failed to send notification after retries` line. README, Notifications: "an HTTP status other than 2xx". `TODO.md` Completed Steps entry in the same commit. Model: opus-5-5
Author
Collaborator

Built in #295: ntfy, Slack and Mattermost now treat a reply with any status outside 200-299, a redirect included, as a failed delivery, retried and logged. The README's Notifications paragraph says which statuses fail.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/dnswatcher/pulls/295: ntfy, Slack and Mattermost now treat a reply with any status outside 200-299, a redirect included, as a failed delivery, retried and logged. The README's Notifications paragraph says which statuses fail. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/dnswatcher#287