Antispam: lessons refused by the engine no longer pass for learned
Found on the NAS, where nothing had been learned in weeks while the UI said "Marked as spam": the source tree predated v1.3.2, so api/worker-* had no controller password and every lesson got 401 — and the trail of state that left behind kept it broken after the password was fixed. - /learn records a lesson only when rspamd accepted it. Recording refused ones made the menu claim "Marked as spam" and its dedup blocked every retry. - Bootstrap: done-markers move to a new key. The old one may have been written by the "-0" bug (a total outage read as a clean run of zero), which left an account marked done with nothing taught and never retried; every older install re-runs the bootstrap once, harmlessly (rspamd skips what it knows). - "Learn from my Spam folder now" in Settings > Antispam filtering queues the bootstrap for the user's accounts at once, instead of the hourly sweep. - webmail.sh update now recreates rspamd: it reads the controller password only when created, so a changed .env reached the app but never the engine. - doctor's advice for the 401 names both real causes (a pre-v1.3.2 compose file, or an rspamd started with an old password) and the fix for each; the old "update v1.3.2" advice could not help. - docs/nas-install.md: how to refresh the source tree on a tarball install. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -397,8 +397,15 @@ print('AUTHORISED')
|
||||
*401*|*Unauthorized*)
|
||||
red " the api container cannot authenticate to the antispam controller."
|
||||
red " Mail will still be classified, but NOTHING will be learned."
|
||||
echo " RSPAMD_CONTROLLER_PASSWORD reaches rspamd but not api/worker-*."
|
||||
echo " fix: webmail.sh update v1.3.2 (or later), which passes it to both"
|
||||
echo " The api and rspamd containers hold different controller passwords. Either:"
|
||||
if [ "$(grep -c RSPAMD_CONTROLLER_PASSWORD "$COMPOSE_FILE")" -lt 3 ]; then
|
||||
echo " - ${COMPOSE_FILE} is older than v1.3.2 and does not give the password"
|
||||
echo " to api/worker-*. fix: refresh the source tree, keeping .env"
|
||||
echo " (docs/nas-install.md §4, 'Refreshing the source tree')"
|
||||
fi
|
||||
echo " - rspamd was started with an older value from .env. fix: webmail.sh update"
|
||||
echo " (it recreates rspamd), or just that container:"
|
||||
echo " docker compose --env-file .env -f docker-compose.yml up -d --no-deps --force-recreate rspamd"
|
||||
ok=1 ;;
|
||||
*"not running"*|*"No such service"*|*"no such service"*|*"is not running"*)
|
||||
ylw " antispam not checked — the stack is not running. Start it, then re-run doctor." ;;
|
||||
@@ -567,6 +574,13 @@ cmd_update() {
|
||||
# stack would look updated while missing a container. --no-recreate so this
|
||||
# only creates what is absent and leaves the rolled services alone.
|
||||
IMAGE_TAG="$target" compose up -d --no-recreate
|
||||
# rspamd holds no state of its own (its Bayes data lives in redis-rspamd), and
|
||||
# it reads RSPAMD_CONTROLLER_PASSWORD only when its container is created. Left
|
||||
# out of the roll it kept whatever password it first started with, so a later
|
||||
# change in .env reached the app but not the engine, and every lesson was
|
||||
# refused with 401 while mail still got classified. Recreating it is a few
|
||||
# seconds of "deliver unclassified", which the filter is built to tolerate.
|
||||
IMAGE_TAG="$target" compose up -d --no-deps --force-recreate rspamd
|
||||
|
||||
echo "== 5/5 health gate (${HEALTH_TIMEOUT}s)"
|
||||
if health_gate; then
|
||||
|
||||
Reference in New Issue
Block a user