---
issue: 112
title: "Scanner: unbounded goroutine fan-out for webhook retries and reconciliation"
severity: medium
domain: Scanner
labels: [bug, scanner, goroutine-leak]
status: open
created: 2026-05-30
source: Full Codebase Audit 2026-05-30
---

# Scanner: unbounded goroutine fan-out for webhook retries and reconciliation

**Severity:** medium
**Domain:** Scanner
**Labels:** bug, scanner, goroutine-leak

## Description

`scanner/main.go:130` spawns goroutines for retry and reconciliation fan-out without any concurrency bound. Under high load or many failed deliveries, the number of live goroutines is unbounded, risking OOM.

## Options

1. Bound with a semaphore/worker pool (e.g. `errgroup` with limit).
2. Process retries in batches sequentially.
3. Rate-limit outbound webhook calls globally.

## Recommendation

Introduce a bounded worker pool (`errgroup.SetLimit` or semaphore) for all retry fan-out paths. Coordinate with ISSUE-111.

## Affected Files

- `scanner/main.go:130`
- `scanner/webhook.go` — retry fan-out

## References

- [Full Codebase Audit 2026-05-30](../09%20-%20Audits/Full%20Codebase%20Audit%20-%202026-05-30.md) — DEC-68
- [[ISSUE-111-scanner-deliverwebhook-goroutines-use-blocking-time-sleep|ISSUE-111]]
