Troubleshooting
Fix a startup error, a backend that won't connect, a sign-in that does nothing or a lost admin account.
On this page
Common problems and where to look. Logs are structured (Pino) and secret-redacted
docker compose logs appis your first stop for almost everything here.
The app won't start#
[env] Environment validation failed - a required variable is missing or
malformed; the message lists each offending key. Check APP_URL (fully-qualified,
no trailing slash), APP_SECRET_KEY/APP_ENCRYPTION_KEY (long enough, not
placeholders), and DATABASE_URL. See Configuration.
OIDC_ENABLED=true but missing required keys - set all five:
OIDC_PROVIDER_ID, OIDC_PROVIDER_NAME, OIDC_ISSUER_URL, OIDC_CLIENT_ID,
OIDC_CLIENT_SECRET.
SMTP configuration is invalid / BOOTSTRAP_ADMIN_* must be set together -
cross-field rules: SMTP_FROM is required with SMTP_HOST; SMTP_SECURE=true
can't combine with SMTP_STARTTLS=required; SMTP_USERNAME/SMTP_PASSWORD are
all-or-nothing; the two bootstrap-admin vars are all-or-nothing.
A migration failed - the boot aborts on purpose rather than running a half-migrated schema. The logs print the pending migrations and where it stopped. Fix the cause (often a DB permission or connectivity issue) and restart.
Build-time placeholder values detected at runtime - NEXT_PHASE is set in
the runtime env, or the deploy didn't override the secrets. Generate real
APP_SECRET_KEY/APP_ENCRYPTION_KEY and unset NEXT_PHASE.
I can't reach a PowerDNS backend#
- URL rejected when adding it - the SSRF guard blocks private-network or
http://URLs by default in production. SetAPP_PDNS_ALLOW_PRIVATE_NETWORKS=trueand/orAPP_PDNS_ALLOW_INSECURE_HTTP=trueas needed (link-local /169.254.169.254is always blocked). See Backends. - Status shows "Not yet reached" / dashboard flags it stale - the app can't
contact the API. Verify the base URL ends in
/api/v1, theX-API-Keymatches PowerDNS'sapi-key, andwebserver-allow-fromon PDNS permits the app's IP. Use the Test button for an immediate probe. - Reachable but no zones - confirm
api=yesand that the API key has access to theserver_idyou configured (almost alwayslocalhost).
Zone or record edits fail on some backends but not others#
Symptom: the same edit succeeds when you retry it, then fails again later, seemingly at random. Usually a permission or read-only error surfaced from PowerDNS rather than from AuthAdmin.
Almost always a group where not every peer can actually accept writes. The peer-selection strategy rotates each request across the group's write targets, so a node that rejects writes takes roughly its share of your edits and the failures look intermittent.
The common shape is a hidden primary whose zones are Native, replicated to
the public nameservers through the database rather than AXFR, where those
public nodes run against a read-only database user. PowerDNS reports them as
primary=no, secondary=no - indistinguishable from a standalone primary - so
AuthAdmin can't detect the difference on its own.
Fix: open each node you only read from under Admin -> PowerDNS servers,
tick Never write to this backend (read-only), and save. Writes then land
only on the real write target, and the group re-labels itself
Primary + secondaries. In provisioning YAML, set write_mode: read_only on
the server row. See
Backends -> Hidden primary.
Note this is unrelated to Use as the default backend, which only picks which backend serves a request that doesn't name one.
Sign-in does nothing / browser DevTools shows "Cookie pda_csrf has been rejected for invalid domain"#
APP_URL's host doesn't match the URL you have in the address bar. The session
and CSRF cookies are scoped to APP_URL's host, so the browser silently drops
them on a mismatch and every login submit looks like it just reloads the page.
The login page renders an inline error when this happens. To fix it: set
APP_URL to the exact scheme + host + port operators type in their browser
(e.g. http://192.168.1.10:3000 if that's how you reach the LAN host, not the
http://localhost:3000 from .env.example). Restart the app and reload the
sign-in page.
OIDC sign-in problems#
redirect_urimismatch at the IdP - register exactly<APP_URL>/api/auth/oidc/<slug>/callback. A wrongAPP_URLis the usual cause.- "Sign-in refused: not authorized" - the email's domain isn't in the
provider's
allowed_email_domains(orOIDC_ALLOWED_EMAIL_DOMAINS), or the user is disabled. - "identity provider did not attest … verified" - the IdP didn't send
email_verified: true. Fix it at the IdP, or (DB providers only) relaxrequireEmailVerified. - Groups don't map to roles - the env provider can't map groups; use a DB
provider. Confirm the IdP emits the groups claim and
claim_groupsmatches; the audit log recordsauth.group_sync.mapping_unresolved(provider slug inafter.provider) for mappings whose role/team/server can't be resolved. - My env provider isn't on the login page - it only hides when a DB provider shares its slug (shadowing). See OIDC.
Email isn't being sent#
With SMTP_HOST unset, mail is skipped by design - verify-email, reset and
email-change links won't go out. Verification and email-change links are
recorded on their audit row (after.url, actions auth.email.verify.sent /
auth.email.change.requested) for an operator to hand over out-of-band. The
password-reset link is only printed once in the server log at warn level (never
in the audit log), so docker compose logs app is where to find it; for a
forgotten password the admin Reset password action on /admin/users/<id> is
the supported alternative. Set the SMTP_* vars to enable delivery. If set but failing, check the logs for
the SMTP error and confirm the encryption mode matches the port (465 implicit
TLS vs 587 STARTTLS). See Configuration.
I'm locked out / lost the admin#
- A failed-login lockout auto-clears after
login_lockout_seconds(default 15 min). - If the Default sign-in method is an IdP that is sending you straight to a
broken login, append
?force-local=1to/loginto get the local form back. - To re-bootstrap an admin, set
BOOTSTRAP_ADMIN_EMAIL+BOOTSTRAP_ADMIN_PASSWORDand restart - the seed ensures that account exists (and won't clobber others).
Re-running provisioning#
Provisioning runs once (guarded by a provisioned_at settings row). To re-apply,
delete that row and restart - see
Provisioning → re-apply.
Still stuck?#
Open an issue with your logs (already secret-redacted) at
github.com/PowerDNS-AuthAdmin/powerdns-authadmin/issues.
For a suspected vulnerability, follow SECURITY.md instead.