Self-hosting
Troubleshooting & FAQ
The issues people hit most when self-hosting Maskin, and how to fix them. Most come down to one missing environment variable — see the configuration reference for the full list.
The UI or session logs don't update live
Real-time updates use PostgreSQL LISTEN/NOTIFY streamed over SSE. Connection poolers (PgBouncer, Supabase's pooled port, etc.) break LISTEN/NOTIFY. Set DATABASE_URL_DIRECT to a non-pooled connection in addition to DATABASE_URL. Also make sure your proxy isn't buffering /api/events responses.
Agent sessions fail to start
- Docker socket: the app launches sessions via
/var/run/docker.sock— confirm it's mounted into the app container and the process can access it. - Image missing: the
agent-baseimage must be built/pulled. In production, setAGENT_BASE_IMAGEto a full registry path (e.g.yourorg/agent-base:latest), not the local:latesttag. - Scaling out: if you use
AGENT_SERVERS, check each server is reachable and itsAGENT_SERVER_SECRETmatches.
MCP calls return 401, or Claude sees no tools
- Check both headers:
Authorization: Bearer ank_…andX-Workspace-Id: <uuid>. - Confirm the URL ends in
/mcpand points at your instance. - In Claude Code, run
/reload-pluginsafter adding the server. See Self-hosted setup.
Integrations won't connect, or stop working
INTEGRATION_ENCRYPTION_KEYmust be set. If it was changed, previously stored tokens can no longer be decrypted — reconnect the affected integrations.- OAuth redirects need a correct public
WEBHOOK_BASE_URL/FRONTEND_URLand the provider's redirect URI registered. See Integrations setup.
Webhooks aren't being received
Set a public WEBHOOK_BASE_URL reachable from the internet; providers deliver to /api/webhooks/<provider>. A 401/403 on delivery usually means a signing-secret mismatch — re-check the provider's secret (e.g. SLACK_SIGNING_SECRET, GITHUB_APP_WEBHOOK_SECRET, LINEAR_WEBHOOK_SECRET).
I can't find my API key / can't sign in on a fresh instance
On an empty database Maskin auto-bootstraps a dev actor, workspace, and API key (controlled by MASKIN_AUTO_BOOTSTRAP, default true) and prints the key in the startup banner. Once you've created your real first workspace and key, set MASKIN_AUTO_BOOTSTRAP=false.
Database / migration errors on boot
Migrations run automatically when the app starts. To run them out of band use pnpm db:migrate. Make sure DATABASE_URL points at a reachable PostgreSQL 16 instance and the role can create tables.
Browser console shows CORS errors
Set CORS_ORIGIN to your frontend origin(s), comma-separated. The dev default is http://localhost:5173.
Agents error with "no model configured"
A workspace needs a model. Add an Anthropic key or Claude subscription, or a custom LLM — Maskin resolves the model through a fixed priority order. See LLM & models.
FAQ
Is Maskin open source? Yes — Apache 2.0, on GitHub.
Can I use models other than Claude? Yes. Point a workspace at any OpenAI-compatible endpoint (OpenRouter, Ollama, vLLM) via a custom LLM — see LLM & models.
Where do I see what a run cost? Each session records token usage and totalCostUsd — see Agents & sessions.
Do I have to self-host? No — managed hosting is available. Book a meeting.
Still stuck? Open an issue on GitHub. For security reports, email the contact on the Security page instead.