Reported from a remote session: ingress answered
`403 External internet access denied - https://sabnzbd.org/access-denied`.
Root cause is `check_access()` in `sabnzbd/interface.py`:
# Never check the XFF header unless access would have been granted
# based on the remote IP alone!
if is_allowed and cfg.verify_xff_header() and (xff_ips := ...):
is_allowed = all(is_local_addr(ip) or is_loopback_addr(ip)
for ip in xff_ips)
nginx's own address is loopback, so the first test passes, and then every
address in X-Forwarded-For has to be local too. Supervisor puts the browser's
address in that header, so anyone reaching Home Assistant from outside the LAN
is refused. `verify_xff_header` defaults to on (`cfg.py:531`), so this is not a
configuration a user opted into.
Reproduced against the running add-on, `GET /config/general/`:
no X-Forwarded-For 200
X-Forwarded-For: 81.164.12.7 403 External internet access denied
X-Forwarded-For: 81.164.12.7, 172.30.32.2 403
X-Forwarded-For: 192.168.1.44 200
which is why it worked on the LAN and not from outside. Verified the fix the
same way, running the shipped nginx.conf and ingress.conf in front of the live
add-on with both variants side by side: the current config 403s on a public
address, the fixed one answers 200 for all three chains, and redirects, static
roots and the API are unaffected. That instance has an empty `url_base`, so the
pass-through routing is now confirmed for both `url_base` values.
The header was forwarded because SABnzbd reads it — the wrong test, since what
it does with it is reject. Clearing it leaves SABnzbd looking at nginx's
loopback address, which is what it saw before the header was added; ingress is
gated by Home Assistant authentication before reaching this proxy either way.
The evidence.md entry records the methodology error, per the skill's own
feed-the-skill rule.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
SKILL.md's step 7 said to match `## X.Y (DD-MM-YYYY)`. The repo does not use
that: 7705 dated CHANGELOG headings are ISO `YYYY-MM-DD` against 363 in
`DD-MM-YYYY`, and the newest entry is ISO in 125 of 135 add-ons. Following the
instruction cost a Copilot review round on #3019.
`DD-MM-YYYY` is not invented, which is presumably how it got written down. It
is what `onpush_builder.yaml` inserts with `date '+%d-%m-%Y'` when a push
arrives with no heading for the config.yaml version, and it is the addons_updater
bot's default in `99-run.sh` — but that bot runs here with `date_iso8601: true`
(confirmed against the running add-on's options), which is why almost everything
on master is ISO. Neither is a reason to write `DD-MM-YYYY` by hand.
The traps.md entry also records that the builder's duplicate check is
`grep -q "^## ${version} ("` — keyed on the exact config.yaml version and blind
to the date — so an ISO heading you wrote yourself still suppresses the bot's
insertion.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
- Synced with upstream birdnet-go; new/updated PRs pending in fork
## 20260826 (26-08-2026)
- Minor bugs fixed
## 20260729.1 (2026-08-01)
- Version renamed from `source-20260729.1`, which Home Assistant could not order and therefore could not reliably offer as an update: every number of the previous version is kept, as a section of its own. The addon itself and the upstream version it tracks are unchanged
- Fixed ingress returning `403 External internet access denied` when Home Assistant is reached from outside the local network. SABnzbd's `verify_xff_header` option, which is on by default, refuses any request whose `X-Forwarded-For` chain contains a non-local address, so the proxy no longer forwards that header.
## 5.1.1.2 (2026-08-25)
- Ingress is now enabled: the WebUI opens directly in the Home Assistant sidebar, and the "Open Web UI" button now goes there. Access by ip:port is unchanged, but has to be typed rather than clicked, as Home Assistant does not allow an add-on to offer both.
- Note for users who set a "Host verification" whitelist in SABnzbd: ingress sends `Host: 127.0.0.1:8080` upstream, because SABnzbd rejects any Host that is not an IP literal. That whitelist therefore no longer filters the ingress route, which is gated by Home Assistant authentication instead. Direct ip:port access is unchanged and still filtered.
# X-Forwarded-For must NOT be forwarded. verify_xff_header defaults to
# on, and check_access() then requires every address in the header to
# be local, so Supervisor's copy of the browser's public address makes
# SABnzbd answer 403 "External internet access denied" for anyone
# reaching Home Assistant from outside the LAN. Clearing it leaves
# SABnzbd looking at nginx's own loopback address. Access is gated by
# Home Assistant authentication before it ever reaches this proxy.
proxy_set_header X-Forwarded-For "";
# The interface itself only emits relative links, so no body
# rewriting is needed. Redirects are the exception: Raiser() emits
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.