Troubleshooting¶
Login & Access¶
How do I get to the admin dashboard after signing in with Steam?¶
If you land on the dashboard: You're an admin. Use the sidebar to access Teams, Servers, Tournament, Settings, etc.
If you land on your player profile:
- You're an admin: Click Dashboard in the top bar, or open the avatar menu (top right) → Dashboard. On your profile page, use the Go to Admin Dashboard button.
- You're not an admin: Only administrators can access the dashboard. See below.
I can't access the admin dashboard – am I an admin?¶
If you upgraded from 1.x to 2.0, see Migrating to 2.0 — you likely need to promote an existing player to admin.
Check your status: After signing in with Steam, open:
(Use the same domain and port as the app, with your browser logged in.) The response shows isAdmin, hasPlayerRecord, reason, and a hint describing what to do.
How admin promotion works:
- First user only: The first Steam user to sign in (when there are no other players) is automatically promoted to admin.
- Fresh DB: If you "restart" or reset the database, all players are wiped. The first person to sign in with Steam after that becomes admin again.
- Already have players? If anyone signed in before you (or players were imported), no one is auto‑promoted. An existing admin must add you as admin manually.
Common mistakes:
- Restarted DB but didn’t sign in first: Someone else signed in before you → they’re admin, you’re not. Have them add you, or reset DB again and be the first to sign in.
- Expecting admin without Steam: Admin is always tied to a Steam ID. Sign in with Steam (or link Steam via Connect Steam if you use Keycloak/Discord/GitHub).
- Not in the players table: You need a player record. Either enable self‑registration (Settings), or have an admin add you.
- Admin status says I'm admin, but admin routes return 401 / "Missing or invalid admin session": This often happens when MAT is behind Cloudflare Tunnel or another reverse proxy. The session cookie can end up set for an internal host, so the browser never sends it. Set
FRONTEND_BASE_URLto the public URL you use in the browser (e.g.https://cs.sivert.io), then restart MAT. See Reverse proxy (nginx, HTTPS) for details.
Debugging: Set LOG_LEVEL=debug and check API logs when you sign in. Look for [Steam callback] Redirect decision (shows isAdmin, redirectTo) and [ensureFirstAdmin] (explains why promotion was skipped or applied).
Server Issues¶
Server Crashes or Plugins Not Working After CS2 Update¶
Symptoms: Server crashes, plugins fail to load, or MatchZy stops working after a CS2 game update.
Solution: CS2 updates often require server and plugin updates. Follow this order:
- Update the CS2 server first using CS2 Server Manager (CSM):
- Use CSM to update your CS2 server to the latest version
- This ensures the server binary matches the current CS2 version
-
See CS2 Server Manager guide for details
-
Then update plugins:
- After the server is updated, update MatchZy and other plugins
- Plugins may be incompatible with older server versions after a CS2 update
- Restart the server after updating plugins
Why this order matters: - CS2 updates can change server APIs that plugins depend on - Updating plugins before the server may cause compatibility issues - CSM ensures the server is on the correct version before plugin updates
If issues persist: - Check server logs for plugin loading errors - Verify plugin versions are compatible with the current CS2 server version - Consider temporarily disabling plugins to isolate the issue
Server Shows Offline¶
Symptoms: Status shows 🔴 Offline
Check:
- Is CS2 server running?
- Is RCON password correct?
- Can API reach server on port 27015?
- Check firewall rules
Fix:
- Verify server is running
- Test RCON:
rcon_address IP:27015; rcon_password PASSWORD; rcon status - Click "Check Status" to refresh
- Reconfigure server with correct RCON password
Match Won't Load¶
Symptoms: "Failed to load match" error
Check:
- Is server status "Online"?
- Is MatchZy plugin loaded? (
css_plugins list) - Can server reach API for webhook?
Fix:
- Verify MatchZy installed
- Check server console for errors
- Try manual RCON:
matchzy_loadmatch_url https://... - Restart CS2 server if needed
Events Not Arriving¶
Symptoms: No real-time updates, player connections not showing. Servers stay "Config sent – no events received yet" or "Not Configured".
Check game server logs/console (CS2 + MatchZy) to see if MatchZy receives the webhook config and sends events. Look for MatchZy startup messages, webhook-related output, or errors. This tells you whether the problem is on the game server side (config not received, wrong URL, etc.) or on the MAT API side (events not reaching us).
Check API logs to see if the game server is actually sending events:
[EVENTS] Incoming webhook— A request reached the API. Look foreventandserver_idin the same log line.[EVENTS] server_configured handled— MatchZy sent its "configured" confirmation; we updatedlast_seenfor that server.[EVENTS] Webhook reachability check (GET /test)— Someone (e.g.curl) hitGET /api/events/test; use this to test connectivity.
If you see no [EVENTS] lines when MatchZy should be sending:
- Test reachability from the game server (or same network):
- Docker:
curl http://YOUR_MAT_IP:3069/api/events/test - Local dev:
curl http://YOUR_MAT_IP:3000/api/events/test - Check API logs for
[EVENTS] Webhook reachability check. If that appears, the API is reachable; MatchZy may not be sending or may be using a different URL. - Verify webhook URL in Settings matches what the game server can reach (often
http://MAT_IP:3069, notlocalhost). - Verify SERVER_TOKEN matches what MatchZy sends (
matchzy_remote_log_header_value). - Check the game server console/logs for MatchZy output (e.g.
[MatchZy] Remote log sent: ...) or errors. This confirms whether MatchZy is receiving config and attempting to send events. - Click Retry on the server card to resend config, then check both game server and API logs again for
[EVENTS] Incoming webhook/server_configured handled. - Check firewall allows inbound on port 3069 (Docker) or 3000 (local dev).
Match Issues¶
Player Can't Connect¶
Symptoms: "Auth rejected" or similar
Fix:
- Verify Steam ID is correct
- Add as backup player:
- Match Details → Player Management
- Search player, select team, add
- Ensure
get5_check_auths trueis set
Veto Not Starting¶
Symptoms: No "Start Veto" button on team page
Check:
- Is tournament started?
- Is match format BO1/BO3/BO5?
- Is match status "ready"?
Fix:
- Verify tournament is in "In Progress" state
- Refresh team page
- If stuck, admin can skip veto
Match Stuck in Warmup¶
Symptoms: Waiting for players, but all are connected
Check:
- Are all players actually ready? (typed
.ready) - Are there 10/10 players?
Fix:
- Check player roster for who's not ready
- Ask players to type
.ready - Or force start: Admin Controls → End Warmup
Scores Not Updating¶
Symptoms: Live scores not changing
Check:
- Are events arriving? (check API logs)
- Is WebSocket connected? (check browser console)
Fix:
- Refresh page
- Check server events endpoint
- Verify match is actually live on server
Bracket Issues¶
Winner Not Advancing¶
Symptoms: Match complete but bracket not updating
Fix:
- Verify match status is "completed"
- Check winner is set correctly
- Manually set winner if needed:
- Click match in bracket
- Set Winner → Select team
- Refresh bracket page
Team Shows as "TBD"¶
Symptoms: Team slot shows "TBD" instead of team name
Explanation: Normal - waiting for previous match
Fix:
- Previous match must complete first
- Winner auto-fills the slot
Network Issues¶
API Server Unreachable¶
Symptoms: CS2 servers can't send webhooks
Fix:
- Test API is reachable (from CS2 server):
- Docker:
curl http://192.168.1.50:3069/api/events/test - Local dev:
curl http://192.168.1.50:3000/api/events/test - Check firewall allows inbound on port 3069 (Docker) or 3000 (local dev)
- Verify the webhook URL in the dashboard Settings matches your setup:
- Docker: typically
https://your-domain.com - Local dev:
http://your-ip:3000 - Use IP address instead of hostname if DNS issues
CS2 Server Unreachable¶
Symptoms: Can't send RCON commands
Fix:
- Check server is running
- Verify port 27015 is open
- Test from API server:
nc -zv server-ip 27015 - Check RCON password is correct
Access Issues¶
Can't Sign In After Upgrade or Lost Admin Access¶
Symptoms: Can't log in, no admin users, or lost admin privileges after upgrade
When to use: This is an advanced recovery method for cases where you can't access the dashboard (e.g., after an upgrade, database migration, or if all admin accounts were removed).
Solution: Manually add or promote a user to admin via direct database access.
Important: Run SQL commands directly on the
matchzy-postgrescontainer. The API container may not havepsqlinstalled or configured correctly.
Method 1: Add a new admin player¶
If the player doesn't exist in the database yet:
docker exec matchzy-postgres psql -U postgres -d matchzy_tournament -c "
INSERT INTO players (
id, name, current_elo, starting_elo, openskill_mu, openskill_sigma,
match_count, is_admin, created_at, updated_at
) VALUES (
'76561198000000001',
'Admin User',
1500, 1500, 25.0, 8.333, 0, 1,
EXTRACT(EPOCH FROM NOW())::bigint,
EXTRACT(EPOCH FROM NOW())::bigint
);
"
Method 2: Promote existing player to admin¶
If the player already exists but isn't an admin:
docker exec matchzy-postgres psql -U postgres -d matchzy_tournament -c "
UPDATE players
SET is_admin = 1, updated_at = EXTRACT(EPOCH FROM NOW())::bigint
WHERE id = '76561198000000001';
"
Troubleshooting: Still redirected to profile after update¶
If you ran the SQL update successfully but still get redirected to your profile when trying to access admin sections:
1. Verify the update worked:
docker exec matchzy-postgres psql -U postgres -d matchzy_tournament -c "
SELECT id, name, is_admin FROM players WHERE id = '76561198000000001';
"
You should see is_admin = 1. If it shows 0 or NULL, the update didn't work.
2. Check Steam ID matches your session:
The Steam ID in the database must match the Steam ID in your login session. Verify:
- The Steam ID you used in the SQL command is correct
- You're logged in with the same Steam account
- Check your session Steam ID: Look at the URL when redirected (/player/76561198000000001) - that's your session Steam ID
3. Log out and log back in:
The session may have cached your old admin status. After updating the database: 1. Log out completely (clear cookies or use incognito/private window) 2. Log back in via Steam 3. The new admin status should be recognized
4. Verify the value is exactly 1:
If is_admin shows as something other than 1, fix it:
docker exec matchzy-postgres psql -U postgres -d matchzy_tournament -c "
UPDATE players
SET is_admin = 1
WHERE id = '76561198000000001';
"
5. Check API logs:
If still not working, check the API logs for auth errors:
Look for messages like "Steam user X is not an admin" - this will show which Steam ID the system is checking.
Note: - Replace
76561198000000001with the actual Steam64 ID - Find your Steam64 ID at steamid.io or steamidfinder.com - If using custom database credentials, adjustPGPASSWORD,-U,-daccordingly - Most common fix: Log out and log back in after running the SQL update
Alternative: Interactive PostgreSQL session¶
If you prefer an interactive session to run multiple queries:
# Connect to PostgreSQL interactively
docker exec -it matchzy-postgres psql -U postgres -d matchzy_tournament
# Then run SQL commands:
UPDATE players SET is_admin = 1, updated_at = EXTRACT(EPOCH FROM NOW())::bigint WHERE id = '76561198000000001';
# Or for a new player:
INSERT INTO players (id, name, current_elo, starting_elo, openskill_mu, openskill_sigma, match_count, is_admin, created_at, updated_at)
VALUES ('76561198000000001', 'Admin User', 1500, 1500, 25.0, 8.333, 0, 1, EXTRACT(EPOCH FROM NOW())::bigint, EXTRACT(EPOCH FROM NOW())::bigint);
# Verify:
SELECT id, name, is_admin FROM players WHERE id = '76561198000000001';
# Exit
\q
Docker Issues¶
Container Won't Start¶
Fix:
# Check logs
docker compose logs api
# Common issues:
# - Port already in use: change PORT environment variable
# - Database connection issues: check DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME env vars
# - Missing environment variables: ensure SERVER_TOKEN and DB_* vars are set
Can't Access from Other Machines¶
Fix:
# Ensure ports are exposed
docker compose ps
# Should show 0.0.0.0:3069->3069
# If not, check docker compose.yml ports section
General Tips¶
Enable Debug Logging¶
Restart API to see detailed logs.
Check Browser Console¶
Press F12 in browser, check Console tab for:
- WebSocket connection errors
- API request failures
- JavaScript errors
Verify Environment¶
# Check all services
docker compose ps # All should be "Up"
# Check API health
curl http://localhost:3069/api/events/test
# Check CS2 server
rcon_address IP:27015
rcon_password PASSWORD
rcon status
Clean Slate Restart¶
If all else fails:
# Restart everything
docker compose down
docker compose up -d --build
# Or without Docker:
yarn build
yarn start
Advanced Setup¶
Build from Source¶
If you've cloned the repository and want to build from source:
git clone https://github.com/sivert-io/matchzy-auto-tournament.git
cd matchzy-auto-tournament
docker compose -f docker/docker-compose.local.yml up -d --build
Local Development (without Docker)¶
For development with hot-reload:
# Install all dependencies for API and client (Yarn workspaces)
yarn install
# Start PostgreSQL (or use your own)
yarn db
# Set environment variables
export SERVER_TOKEN=your-server-token
export DB_HOST=localhost
export DB_PORT=5432
export DB_USER=postgres
export DB_PASSWORD=postgres
export DB_NAME=matchzy_tournament
# Start in dev mode (API + client)
yarn dev
Frontend: http://localhost:5173
API: http://localhost:3000
Configure Webhook URL:
When you start the dev server, you'll see output like:
[CLIENT] VITE v5.4.21 ready in 450 ms
[CLIENT]
[CLIENT] ➜ Local: http://localhost:5173/
[CLIENT] ➜ Network: http://192.168.2.5:5173/
[CLIENT] ➜ Network: http://100.110.237.14:5173/
[CLIENT] ➜ Network: http://192.168.10.158:5173/
- Go to Settings in the dashboard
- Set the Webhook URL to the API endpoint:
- If CS2 servers are on the same machine:
http://localhost:3000 - If CS2 servers are on the network: Use one of the Network IPs shown above, but change the port to
3000(e.g.,http://192.168.2.5:3000) - Use whichever IP your CS2 servers can reach
- Click "Save Settings"
Note: The frontend runs on port
5173, but webhooks must point to the API on port3000.
Docker Architecture¶
The Docker setup uses Caddy as a reverse proxy:
- Frontend app at
/(root) - API at
/api - Everything runs on port 3069 — just expose this single port for production
Multi-Architecture Support:
amd64/x86_64(Intel/AMD 64-bit)arm64/aarch64(ARM 64-bit, e.g., Apple Silicon, Raspberry Pi 4+)armv7/armv6(ARM 32-bit, e.g., older Raspberry Pi)
Network Configuration¶
Private Network (LAN):
- Everything on
192.168.x.x- works out of the box - Share team pages with local IPs
Public Internet:
- Get a domain or use public IP
- Expose/proxy port 3069 only
- Set webhook base URL in Settings to your public domain
Recommended: Run on private network, expose via reverse proxy if needed.
Reverse proxy & HTTPS¶
If you put MAT behind nginx (or another reverse proxy) with HTTPS, see Reverse proxy (nginx, HTTPS). The guide includes a full nginx example, required headers (X-Forwarded-Proto, Host), and how to set FRONTEND_BASE_URL.
"Only works with HTTP" behind HTTPS: Some admins find MAT works only when they set FRONTEND_BASE_URL=http://... in .env even though the site is served over HTTPS. This usually means the proxy is not sending X-Forwarded-Proto: https. Add proxy_set_header X-Forwarded-Proto $scheme; in nginx, then use https://your-domain.com in FRONTEND_BASE_URL. See the reverse-proxy guide for details.
Getting Help¶
If you're still stuck:
- Join our Discord Community: https://discord.gg/n7gHYau7aW - Get real-time support, share ideas, and connect with other tournament hosts
- Check GitHub Issues: https://github.com/sivert-io/matchzy-auto-tournament/issues
- Start a Discussion: https://github.com/sivert-io/matchzy-auto-tournament/discussions
When asking for help, please include: - What you were trying to do - Error messages (API logs, CS2 console) - Browser console errors (if frontend issue) - Your setup (Docker/local, network config)