Troubleshooting
Windows Path Errors in config.toml
”invalid escape” or “expected eight hexadecimal digits after ‘\U’”
TOML treats backslashes inside double-quoted strings as escape characters. A native Windows path like "C:\Users\you\Downloads\client_secret.json" triggers a parse error because \U is interpreted as a Unicode escape sequence and \D is an invalid escape.
Fix: use forward slashes or single-quoted strings in your config file:
# Option 1: forward slashes (recommended)[oauth]client_secrets = "C:/Users/you/Downloads/client_secret.json"
# Option 2: single-quoted string (backslashes are literal)[oauth]client_secrets = 'C:\Users\you\Downloads\client_secret.json'See Configuration: Windows paths for more detail.
OAuth Errors
”Error 403: access_denied”
Your email isn’t added as a test user. Go to OAuth consent screen > Test users and add your Gmail address. For Workspace accounts using a named OAuth app, add the test user in that org’s Google Cloud project.
”Access blocked: This app’s request is invalid”
The Gmail scope isn’t configured. Verify you added gmail.modify on the Data Access page and that Gmail API is enabled in your Google Cloud project.
”Access blocked” or “app not approved” for Workspace accounts
The Workspace organization restricts OAuth to apps created within their org. Create a separate Google Cloud project inside the org and configure it as a named OAuth app. See OAuth Setup: Google Workspace Accounts.
”redirect_uri_mismatch”
Wrong application type. Ensure you selected Desktop app when creating OAuth credentials.
”OAuth client is missing redirect_uris”
You created a “TVs and Limited Input devices” OAuth client, which doesn’t work with Gmail. Google’s device code flow does not support Gmail scopes. Create a new OAuth client with Desktop app type instead.
General OAuth Issues
- Remove old tokens:
rm ~/.msgvault/tokens/you@gmail.com.json - Re-add account:
msgvault add-account you@gmail.com - Revoke and retry: myaccount.google.com/permissions
Headless Server Issues
”No browser available”
The standard OAuth flow requires a browser. For headless servers, use the copy-token workflow:
- Authorize on a machine with a browser:
msgvault add-account you@gmail.com - Copy the token file to your server:
scp ~/.msgvault/tokens/you@gmail.com.json user@server:~/.msgvault/tokens/ - Register on the server:
msgvault add-account you@gmail.com
Run msgvault add-account you@gmail.com --headless to see detailed instructions with the exact paths for your configuration.
Token copied but “account not found”
After copying the token, you must run msgvault add-account you@gmail.com on the headless server to register the account in the database. This command detects the existing token and registers the account without opening a browser.
Remote Deployment Issues
export-token says HTTPS is required
msgvault export-token enforces HTTPS by default. Most deployments use Tailscale or a home LAN where HTTP is fine — add --allow-insecure:
msgvault export-token you@gmail.com --to http://nas-ip:8080 --api-key KEY --allow-insecureTo avoid passing the flag every time, run msgvault setup with a remote server configured (it sets allow_insecure = true in your local config automatically), or add it manually:
[remote]allow_insecure = trueexport-token returns 401/Forbidden
- Verify your remote server has an
api_keyin[server]. - Confirm
MSGVAULT_REMOTE_API_KEY/--api-keymatches that value. - Ensure the remote endpoint is reachable from the local machine.
Remote command behaves unexpectedly
Commands that support remote mode (search, show-message, stats, list-accounts) can be triggered unintentionally when [remote].url is set.
Use --local when you want to force local SQLite:
msgvault search from:alice@example.com --localmsgvault list-accounts --localDocker Container Issues
Container won’t start
Check logs first:
docker logs msgvaultCommon causes:
- Missing
config.tomlwith[oauth] client_secretsand[server] bind_addr = "0.0.0.0"+api_key - Port 8080 already in use — change
api_portin config or the port mapping in docker-compose.yml - Volume mount permissions — on Synology, add
user: rootto docker-compose.yml (see Platform Notes)
permission denied on Synology
Synology ACLs override standard Unix permissions. Add user: root to your docker-compose.yml:
services: msgvault: image: ghcr.io/wesm/msgvault:latest user: root # ... rest of configScheduled sync not running
-
Verify accounts are configured in
config.toml:[[accounts]]email = "you@gmail.com"schedule = "0 2 * * *"enabled = true -
Verify the token exists:
Terminal window docker exec msgvault ls -la /data/tokens/ -
Check scheduler status:
Terminal window curl -H "X-API-Key: KEY" http://localhost:8080/api/v1/scheduler/status -
Make sure you’ve run the initial full sync — the scheduler only runs incremental syncs:
Terminal window docker exec msgvault msgvault sync-full you@gmail.com
“No source found for email”
The account isn’t registered in the database. Re-export the token from your local machine:
msgvault export-token you@gmail.com --to http://nas-ip:8080 --api-key KEY --allow-insecureThis uploads the token and registers the account. If the token file already exists on the server, register it directly:
docker exec msgvault msgvault add-account you@gmail.comRate Limiting
If you hit Gmail API rate limits during large syncs:
- Reduce
rate_limit_qpsin config (default: 5) - Use
--limitduring initial testing - Wait and retry. Rate limits reset over time
Database Corruption
If the database is corrupted:
- Back up your database:
cp ~/.msgvault/msgvault.db ~/.msgvault/msgvault.db.bak - Delete and re-sync:
Terminal window rm ~/.msgvault/msgvault.dbmsgvault init-dbmsgvault sync-full you@gmail.com
Interrupted Syncs
Run the same sync command again. It resumes from the last checkpoint:
msgvault sync-full you@gmail.com --after 2024-01-01 --before 2024-02-01To force a fresh start:
msgvault sync-full you@gmail.com --noresumeCGO / Build Errors
If you get errors about missing C compiler:
- macOS: Install Xcode Command Line Tools:
xcode-select --install - Linux: Install GCC:
apt install gccordnf install gcc
CGO is required for mattn/go-sqlite3 (FTS5 support).
TUI Not Showing Data
If the TUI launches but shows no data:
- Verify sync completed:
msgvault stats - Rebuild the Parquet cache:
msgvault build-cache --full-rebuild - Check account filter: try
msgvault tuiwithout--account
Web Server Issues
”api_key is required for non-loopback bind address”
You set bind_addr to a non-loopback address (e.g., 0.0.0.0) without configuring an API key. Either add an api_key to your [server] config, or set allow_insecure = true if you understand the security implications. See Web Server: Security Model.
Port already in use
Another process is using the configured port. Either stop the other process, or change api_port in your [server] config:
[server]api_port = 9090HTTP 429 Too Many Requests
The API server enforces a rate limit of 10 requests per second per client IP. If you are hitting this limit, space out your requests or check the Retry-After response header for the wait duration.
Using Logs for Troubleshooting
Enable file logging to capture detailed diagnostics. Add this to your config.toml:
[log]enabled = trueThen reproduce the issue. Each run gets a unique correlation ID (run_id) so you can isolate its log lines:
# View today's logmsgvault logs
# Follow live while reproducing an issuemsgvault logs -f
# Filter to a specific runmsgvault logs --run-id <id>
# Show only errorsmsgvault logs --level errorFor one-off debugging without changing config, use the --log-file flag:
msgvault sync --log-file /tmp/debug.log --log-level debugTo trace slow SQL queries, lower the threshold or enable full SQL tracing:
# Log queries slower than 50msmsgvault tui --log-sql-slow-ms 50
# Log every SQL query (verbose)msgvault tui --log-sqlLog files are stored in <data_dir>/logs/ by default. Run msgvault logs --path to print the directory. See Configuration: Log for all options.
Still Stuck?
Ask for help on the msgvault Discord server or open an issue on GitHub.