From 3e99ab2af6119521608793e941bfe1181106e754 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Fri, 13 Nov 2026 17:16:51 -0800 Subject: [PATCH] fix(sentry-apps): Stop retrying service hooks to blocked or unreachable URLs Service hooks retried every failure three times and reported the final one to Sentry. Most of those failures are on the customer's side: hook URLs that resolve to a blocked IP, DNS lookups that fail, or endpoints that reset the connection. A blocked IP is now not retried at all, and network errors still retry but aren't reported once retries run out. Anything else (db, nodestore, payload errors) retries and reports like before. Fixes SENTRY-4AGK Fixes SENTRY-5R70 Co-Authored-By: Claude Opus 5.5 --- src/sentry/sentry_apps/tasks/service_hooks.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sentry/sentry_apps/tasks/service_hooks.py b/src/sentry/sentry_apps/tasks/service_hooks.py index 234ef41b96ce..51001a1ba89f 100644 --- a/src/sentry/sentry_apps/tasks/service_hooks.py +++ b/src/sentry/sentry_apps/tasks/service_hooks.py @@ -1,10 +1,12 @@ from time import time from typing import Any, cast +from requests.exceptions import RequestException from taskbroker_client.retry import Retry from sentry import features, nodestore from sentry.api.serializers import serialize +from sentry.exceptions import RestrictedIPAddress from sentry.http import safe_urlopen from sentry.models.group import Group from sentry.sentry_apps.models.servicehook import ServiceHook @@ -67,8 +69,12 @@ def kick_off_service_hooks(event: GroupEvent, has_alert: bool) -> None: @instrumented_task( name="sentry.sentry_apps.tasks.service_hooks.process_service_hook", namespace=sentryapp_tasks, - retry=Retry(times=3, delay=60 * 5, on=(Exception,)), + # A hook URL that resolves to a blocked IP never succeeds, so don't retry it. + # Network failures from the customer's endpoint still retry, but aren't + # reported once retries run out since there's nothing for us to fix. + retry=Retry(times=3, delay=60 * 5, on=(Exception,), ignore=(RestrictedIPAddress,)), silo_mode=SiloMode.CELL, + silenced_exceptions=(RestrictedIPAddress, RequestException), ) def process_service_hook( servicehook_id: int, project_id: int, group_id: int, event_id: str