Skip to content

Troubleshooting

Common problems and fixes when running a self-hosted Minder instance. Every service runs as a Docker container named minder-<service>, provisioned and managed through the bash setup.sh entrypoint (see Self-hosting). Configuration lives in the root ./.env, which is the single source of truth — edit it there, then apply with a restart.

Note

Host ports are loopback-bound, so curl http://localhost:<port> works on the box itself. By default only the API Gateway (8000) and the web client (8009) publish one; reach the other core APIs through the gateway, or set MINDER_DEV_PORTS=1 in .env and restart to publish them for debugging. The commands below assume you are on the host, in your Minder checkout.

To see every core service's health at once (including platform-ops, which serves bundles, container logs and backups), ask the gateway:

curl -s http://localhost:8000/v1/status | jq '.services[] | {name, status}'

A service won't start

Check the logs first:

bash setup.sh logs <service>
# or
docker logs minder-<service> --tail 100

Common causes:

  1. A configuration error or missing environment variable — check the root ./.env.
  2. A dependency (Postgres, Redis, Qdrant, Neo4j) that isn't ready yet.
  3. A port conflict on the host.
  4. Insufficient resources — on modest hardware such as a Raspberry Pi 4, RAM is tight.

Recreate a service after fixing its config:

bash setup.sh restart <service>

Find what is holding a conflicting port:

lsof -i :8000
# then stop the offending process, or adjust the port mapping

A service shows "no-healthcheck" — is it broken?

Usually no. A few containers have no healthcheck by design, because their base images lack the tooling a health probe would need:

  • minder-otel-collector
  • minder-redis-exporter
  • minder-rabbitmq-exporter

docker ps shows these with no health status. That is expected — it is not an "unhealthy" state. Confirm they are working from their logs, not their health:

docker logs minder-otel-collector --tail 30
docker logs minder-redis-exporter --tail 30
docker logs minder-rabbitmq-exporter --tail 30

Database issues

Can't connect to PostgreSQL

docker exec minder-postgres pg_isready -U minder
docker exec minder-postgres psql -U minder -c "SELECT 1;"
docker logs minder-postgres --tail 50

Migration failed

# Re-run migrations
bash setup.sh migrate

# Or apply a SQL file directly
docker exec -i minder-postgres psql -U minder -d minder < migration.sql

Fresh reset destroys data

A full reset wipes every volume and cannot be undone. Only use it on a development instance you are willing to lose.

docker compose down -v      # deletes all data
bash setup.sh start

Redis authentication

Symptom:

AUTH failed: WRONGPASS invalid username-password pair or Redis is loading from disk

Cause: the password being used doesn't match the one Redis is running with.

Fix / verify:

# Confirm the password in the root .env (source of truth)
grep REDIS_PASSWORD .env

# Test with it
docker exec minder-redis redis-cli -a "$REDIS_PASSWORD" ping   # -> PONG

# If needed, restart Redis
bash setup.sh restart redis
docker logs minder-redis --tail 50

Note

Always edit the root ./.env. Any generated per-service env file is rewritten from the root file by setup.sh on every start/restart, so edits there are lost.

Neo4j not ready

Neo4j takes time to start. It backs the marketplace (plugin dependency graph) and graph-RAG (knowledge graph).

# Wait for it to finish starting
docker logs minder-neo4j --tail 50 | grep -i "started\|remote interface"

# Test a query
docker exec minder-neo4j cypher-shell -u neo4j -p "$NEO4J_PASSWORD" "RETURN 1;"

# Check the password
grep NEO4J .env

Plugin not loading

The first-party module plugins ship with the platform and are loaded from disk on startup, so a clean install already lists them — the plugin list should not be empty. See Plugins for the plugin model, and the plugin trust model for how plugins are isolated.

# Registry health and plugin list
docker exec minder-api-gateway curl -s http://minder-plugin-registry:8001/health
curl http://localhost:8000/v1/plugins

# Registry logs
docker logs minder-plugin-registry --tail 50

Memory / resource pressure

# Per-container usage
docker stats --no-stream

# Reclaim space from unused Docker resources
docker system prune -a

# Look for OOM kills
docker logs minder-<service> | grep -i "memory\|oom\|out of"

On low-RAM hosts, the AI services (RAG pipeline, model management) and Ollama inference are the heaviest. Stop non-critical services temporarily if the host is starved. See AI setup for pointing inference at an external Ollama to offload the box.

Services can't communicate

# Network exists?
docker network ls | grep minder

# Service-to-service check (by container name)
docker exec minder-api-gateway curl -s http://minder-rag-pipeline:8004/health

# Bring the stack back consistently
bash setup.sh restart

Services address each other by container name on the minder-network Docker network.

Routing returns 404

Minder fronts its services with Traefik v3. Only services with the right Docker labels are routed, so a missing label (not a down service) is a common cause of a 404.

docker logs minder-traefik --tail 50
bash setup.sh restart traefik

Auth redirects are expected on protected routes

Several routes sit behind Authelia forward-auth. Unauthenticated requests to them are redirected (302) to the Authelia login portal — that is working as intended, not an error. Full browser SSO still requires real DNS and valid TLS on the deployment (see Using Minder).

API requests return 401

Access tokens are short-lived (15 minutes by default). A 401 usually means the token expired: renew it with POST /v1/auth/refresh, or sign in again if refresh also returns 401 (the session reached its 24-hour cap, the account was deactivated, or its sessions were revoked). A stale token is refused even on routes that work without one, so leave the Authorization header out to make an anonymous request. See Authentication → Token lifetime & sessions.

Slow API responses

# Resource usage
docker stats --no-stream

# Turn up logging: set LOG_LEVEL=DEBUG in the root ./.env, then
bash setup.sh restart <service>

# Check DB connection count
docker exec minder-postgres psql -U minder -c \
  "SELECT count(*) FROM pg_stat_activity;"

Getting help

Collect diagnostics before asking for help:

bash setup.sh status > status.txt
bash setup.sh doctor > doctor.txt
docker ps -a > containers.txt
docker stats --no-stream > stats.txt

Useful commands

docker ps                               # service status
docker stats --no-stream                # resource usage
docker logs minder-<service> --tail 50  # service logs
bash setup.sh restart <service>         # restart a service
bash setup.sh doctor                    # environment diagnostics