When configuring the tracker database via a MySQL DSN (for example
mysql://user:password@host:3306/db), any reserved URL characters in the password (notably + and
/) must be percent-encoded. Otherwise, the DSN may be parsed incorrectly and the tracker will fail
to connect to MySQL.
-
Our
application/compose.yamlsets the tracker DSN using environment variables. -
The DSN is constructed like:
TORRUST_TRACKER_CONFIG_OVERRIDE_CORE__DATABASE__PATH= mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql:3306/${MYSQL_DATABASE} -
If
MYSQL_PASSWORDcontains reserved characters, the DSN becomes invalid unless the password is URL-encoded first. -
Resolution applied here: we use URL-safe secrets (alphanumeric plus
-and_) in environment files where credentials are embedded in URLs.
The database URL is a standard URI. The password component follows URL-encoding rules. Characters
like +, /, @, :, #, ?, &, and % are reserved in URLs and must be percent-encoded
inside credentials to avoid ambiguity.
- Tracker fails to start or cannot connect to MySQL
- MySQL auth errors despite correct credentials
- Logs may show DSN/parse or auth failures
-
Prefer URL-safe secrets for DSN credentials
- Generate secrets using only unreserved/URL-safe chars (for example
A-Za-z0-9_-).
# 48-char URL-safe secret openssl rand -base64 48 | tr '+/' '-_' | tr -d '=' | cut -c1-48
- Generate secrets using only unreserved/URL-safe chars (for example
-
Percent-encode the password for use in the DSN
- Encode once before injecting into the DSN:
python3 - << 'PY' from urllib.parse import quote pw = input().strip() print(quote(pw, safe='')) PY
- Then set
MYSQL_PASSWORD_ENC=<encoded>and reference that in the DSN instead of the raw password.
- Use URL-safe secrets by default for any credential that will be embedded in URLs/DSNs.
- If non-URL-safe secrets are required, percent-encode them before constructing the DSN.
infrastructure/config/environments/staging-hetzner-staging.envupdated to use URL-safeMYSQL_ROOT_PASSWORDandMYSQL_PASSWORD.
- Document that MySQL DSNs require URL-encoding of credentials.
- Optionally provide examples and/or allow alternative config fields where user/password are provided separately from the DSN.