Summary
In nfrastack/db-backup:4.9.0 the MSSQL client tools are missing from the image, so every MSSQL backup fails. The Containerfile intends to install them on both amd64 and arm64, but MSSQL_VERSION has a leading 1 typo, so the download and the subsequent apk add fail during the build.
Symptom
An MSSQL job fails in under a second, every run. By default the cause is invisible — silent wraps the sqlcmd call and the routine still reports exit code 0:
[NOTICE] ** [01-...__vault] Dumping MSSQL database: 'vault'
[ERROR] ** [01-...__vault] DB Backup of 'mssql_vault_..._20260824-123429.bak.zst' reported errors
[ERROR] ** [01-...__vault] Skipping encryption because backup did not complete successfully
[ERROR] ** [01-...__vault] Skipping moving DB Backup to final location because backup did not complete successfully
[INFO] ** [01-...__vault] Backup 01 routines finish time: ... with exit code 0
With SHOW_OUTPUT=TRUE the actual error appears:
sudo: /opt/mssql-tools18/bin/sqlcmd: command not found
Evidence from inside the container
Architecture is x86_64, i.e. the supported path:
# uname -m
x86_64
# ls /opt
microsoft mysql
# find /opt/microsoft
/opt/microsoft
/opt/microsoft/msodbcsql18
/opt/microsoft/msodbcsql18/ACCEPT_EULA
# find / -name 'sqlcmd*' -not -path '/proc/*'
(no output)
# apk info | grep -iE 'sql|odbc'
postgresql-common
postgresql18-client
sqlite
sqlite-libs
Neither msodbcsql18 nor mssql-tools18 is installed. The only trace of the MSSQL block is the ACCEPT_EULA marker, which is created by mkdir -p/touch before the two curl/apk add calls — so the block starts and then fails.
Cause
Containerfile:
MSODBC_VERSION=18.6.1.1-1 \
MSSQL_VERSION=118.6.1.1-1 \
MSSQL_VERSION has a leading 1. The resulting URL
https://download.microsoft.com/download/b60bb8b6-.../mssql-tools18_118.6.1.1-1_amd64.apk
does not exist. Since curl -sSL -O is used without -f, the failure is not surfaced as a non-zero exit; the apk add of both packages then fails, and with it the whole && chain in that if block — after the EULA marker has been created. CHANGELOG.md for 4.1.99 states MSSQL 18.6.1-1, which matches 18.6.1.1-1, the value already used for MSODBC_VERSION.
Suggested fix
- MSSQL_VERSION=118.6.1.1-1 \
+ MSSQL_VERSION=18.6.1.1-1 \
Two hardening suggestions while you're in there:
- Add
-f (or --fail-with-body) to the curl -O calls in the MSSQL block, so a bad URL fails the build instead of producing a file that apk then rejects.
- Consider not routing the
sqlcmd invocation through silent at rootfs/container/functions/10-dbbackup:532, or at least logging its stderr on a non-zero exit. As it stands, a missing client is indistinguishable from a wrong password or a permissions problem, and the run still ends with exit code 0.
Environment
- Image:
nfrastack/db-backup:4.9.0 (Docker Hub, amd64; also present in the 2026-08-23 rebuild)
- Base: Alpine 3.24.1
- Host: x86_64, Docker standalone
DB_TYPE=mssql, DB01_MSSQL_MODE default (DATABASE), target is a ghcr.io/bitwarden/mssql container
Not mentioned in the 4.9.0 or 4.9.1 changelog entries, so I assume it is unnoticed rather than known.
Summary
In
nfrastack/db-backup:4.9.0the MSSQL client tools are missing from the image, so every MSSQL backup fails. TheContainerfileintends to install them on both amd64 and arm64, butMSSQL_VERSIONhas a leading1typo, so the download and the subsequentapk addfail during the build.Symptom
An MSSQL job fails in under a second, every run. By default the cause is invisible —
silentwraps thesqlcmdcall and the routine still reportsexit code 0:With
SHOW_OUTPUT=TRUEthe actual error appears:Evidence from inside the container
Architecture is
x86_64, i.e. the supported path:Neither
msodbcsql18normssql-tools18is installed. The only trace of the MSSQL block is theACCEPT_EULAmarker, which is created bymkdir -p/touchbefore the twocurl/apk addcalls — so the block starts and then fails.Cause
Containerfile:MSSQL_VERSIONhas a leading1. The resulting URLdoes not exist. Since
curl -sSL -Ois used without-f, the failure is not surfaced as a non-zero exit; theapk addof both packages then fails, and with it the whole&&chain in thatifblock — after the EULA marker has been created.CHANGELOG.mdfor 4.1.99 statesMSSQL 18.6.1-1, which matches18.6.1.1-1, the value already used forMSODBC_VERSION.Suggested fix
Two hardening suggestions while you're in there:
-f(or--fail-with-body) to thecurl -Ocalls in the MSSQL block, so a bad URL fails the build instead of producing a file thatapkthen rejects.sqlcmdinvocation throughsilentatrootfs/container/functions/10-dbbackup:532, or at least logging its stderr on a non-zero exit. As it stands, a missing client is indistinguishable from a wrong password or a permissions problem, and the run still ends withexit code 0.Environment
nfrastack/db-backup:4.9.0(Docker Hub, amd64; also present in the 2026-08-23 rebuild)DB_TYPE=mssql,DB01_MSSQL_MODEdefault (DATABASE), target is aghcr.io/bitwarden/mssqlcontainerNot mentioned in the 4.9.0 or 4.9.1 changelog entries, so I assume it is unnoticed rather than known.