Troubleshooting
Cannot Connect to Server
Symptoms: Browser shows "connection refused", "ERR_CONNECTION_TIMED_OUT", or "unable to reach server".
Check these in order:
-
Server is running:
docker compose ps # or systemctl status vaultctl -
Correct URL: Ensure you are using
https://(nothttp://) and the correct port. The default is443if behind a reverse proxy, or8080for the raw server. -
TLS certificate: If using a self-signed certificate, your browser may block the connection. Accept the certificate or configure a trusted CA.
-
Firewall: Ensure the port is open:
# Check if the port is listening ss -tlnp | grep 8080 -
Reverse proxy: If using Caddy or nginx, check the proxy logs:
docker compose logs caddy # or journalctl -u nginx
Login Fails
Symptoms: "Invalid credentials" error after entering correct password.
- Caps Lock: Verify Caps Lock is off. The master password is case-sensitive.
- Account locked: After 5 consecutive failed attempts, the account is locked for 15 minutes (configurable via
LOCKOUT_DURATION). Wait and try again. - KDF mismatch: If you changed KDF parameters after registration (not recommended), the client may derive a different auth hash. Use the same parameters that were set during account creation.
If your account is locked, you will receive an ACCOUNT_LOCKED error. The lockout expires automatically — there is no manual unlock.
Slow Login
Symptoms: Login takes 2-5 seconds or more.
This is expected behavior. vaultctl uses Argon2id with 64 MB of memory and 3 iterations for key derivation. This is intentionally slow to make brute-force attacks impractical.
- 2-5 seconds is normal on modern hardware.
- Older or low-memory devices may take longer.
- Do not reduce KDF parameters to speed up login — this weakens security.
Browser Extension Not Autofilling
Symptoms: The extension icon appears but does not fill in credentials.
-
Check permissions: Ensure the extension has permission to access the current site. Click the extension icon and check site access settings.
-
Check URI match: The extension matches saved items by URI. If the saved URI is
https://example.com/loginbut you are onhttps://example.com/app/login, the match may fail. Edit the item and update the URI, or add multiple URIs. -
Multiple matches: If multiple items match, the extension shows a dropdown instead of autofilling. Click the extension icon and select the correct item.
-
Iframe isolation: Some sites use iframes for login forms. The extension may not have access to iframe contents depending on browser security settings.
429 Rate Limited
Symptoms: API returns {"error": {"code": "RATE_LIMITED", "message": "too many requests"}}.
The server enforces rate limits to prevent abuse:
| Scope | Default Limit |
|---|---|
| Per IP | 60 requests/min |
| Per email (auth endpoints) | 5 attempts / 15 min |
Resolution:
- Wait for the
Retry-Afterheader value (in seconds) before retrying. - If you are hitting the per-IP limit from scripts or automation, increase
RATE_LIMIT_RPMin the server configuration. - If you are hitting the per-email limit, wait 15 minutes or adjust
AUTH_RATE_LIMIT_WINDOW.
500 Internal Server Error
Symptoms: API returns {"error": {"code": "INTERNAL", "message": "internal server error"}}.
-
Check server logs:
docker compose logs vaultctl --tail 100 # or journalctl -u vaultctl --since "5 minutes ago" -
Database connectivity: Verify PostgreSQL is running and the
DATABASE_URLis correct:docker compose exec db pg_isready -
Missing environment variables: Ensure all required env vars are set. See Server Configuration.
-
Disk space: Check available disk space. PostgreSQL may refuse writes if the disk is full.
-
Report the issue: If the error persists, open an issue on GitHub (opens in a new tab) with the relevant log output (redact any sensitive values).
Server logs may contain request metadata. The LOG_REDACT_FIELDS environment variable controls which fields are redacted. Ensure sensitive fields are redacted before sharing logs publicly.