Troubleshooting
Common issues and diagnostic commands.
Pods Stuck in Pending
The cluster may lack sufficient resources.
kubectl describe pod -n boltmcp <pod-name>Look for events mentioning insufficient CPU or memory. Either scale the cluster or set resource requests in your values file.
CreateContainerConfigError / Missing Secret
The chart never creates the three application Secrets — pods fail with CreateContainerConfigError: secret "boltmcp-database" not found (or -oidc / -auth) until you create them. List what's actually present:
kubectl get secrets -n boltmcpIf any of boltmcp-database, boltmcp-oidc, boltmcp-auth is missing, create it per Cluster Prep → Application Secrets. Pods recover automatically on the next restart loop once the Secret exists.
CrashLoopBackOff
The application is crashing on startup. Check logs:
kubectl logs -n boltmcp <pod-name>Common causes:
- Wrong database password — the password baked into PostgreSQL on first startup must match the
web-password/mcp-server-password/playground-password/keycloak-passwordin yourboltmcp-databaseSecret. If you rotated a value in the Secret without resetting the corresponding DB user viaALTER USER ... PASSWORD ..., they'll diverge. Reset the password in the database or roll back the Secret value. - Missing key in a Secret — if the chart references a key that doesn't exist in the user-managed Secret (e.g.
mcp-inspector-proxy-auth-tokenwhilemcpInspector.enabled=true), pods fail to start.kubectl describe podshows the missing key. Edit the Secret to add the key, thenkubectl rollout restart deployment/<service>. - Database not ready — the init container should wait, but verify the database pod is healthy.
ErrImagePull / ImagePullBackOff
Kubernetes cannot pull the container images.
kubectl describe pod -n boltmcp <pod-name>Verify the image pull secret exists:
kubectl get secrets -n boltmcp | grep boltmcp-pull-secretIf missing, recreate it:
kubectl create secret docker-registry boltmcp-pull-secret \
-n boltmcp \
--docker-server=europe-west2-docker.pkg.dev \
--docker-username=_json_key \
--docker-password="$(cat ./key.json)"The chart's default global.imagePullSecrets is [{ name: boltmcp-pull-secret }], so as long as the Secret exists under that name in the install namespace it will be picked up on the next pod restart (a helm upgrade is only required if you used a non-default Secret name and need to override the value).
Connection Refused
- Pod not ready — check pod status with
kubectl get pods -n boltmcp - Service not found — verify services exist with
kubectl get svc -n boltmcp - Ingress or DNS misconfigured — bypass them with port-forwarding (see below) to confirm the pod itself is healthy
Bypass Ingress with Port-Forwarding
If the Ingress, DNS, or TLS layer is misbehaving, port-forward directly to a service to confirm the pod is responding. This is a diagnostic tool, not a normal access path.
# Web app
kubectl port-forward -n boltmcp svc/boltmcp-web 3000:3000
# Keycloak
kubectl port-forward -n boltmcp svc/boltmcp-keycloak 8080:8080
# Playground
kubectl port-forward -n boltmcp svc/boltmcp-playground 3002:3002
# MCP Server
kubectl port-forward -n boltmcp svc/boltmcp-mcp-server 3001:3001Note: OIDC redirects will fail when accessed via localhost, since the issuer URL in the values file points at your public Keycloak hostname. Port-forwarding is useful for verifying a single service is up, not for an end-to-end auth flow.
Keycloak's admin UI is a special case: with keycloak.production.enabled: true (the default), KC_HOSTNAME is enforced, so the admin console will load briefly via localhost:8080 and then redirect you to https://auth.boltmcp.example.com. Use the public Keycloak URL for admin work; port-forwarding to Keycloak is only useful for hitting /health/ready to confirm the pod is up.
Authentication Not Working
Issuer URL Mismatch
The OIDC issuer URL must be identical in the browser and in the application pods:
kubectl describe pod <web-pod> -n boltmcp | grep OIDCEnsure the issuer URL matches the Keycloak hostname exactly (protocol, host, port, path).
Missing Email or Name
BoltMCP requires users to have an email and first name to sign in. The auto-provisioned boltmcp_admin user gets both fields set at realm-import time (email from oidc.adminUser.email, firstName Admin). If you add more users later through the Keycloak admin console, make sure each has both fields populated before they try to sign into the BoltMCP web app.
Client Secret Mismatch
The three OIDC client secrets in the boltmcp-oidc Secret must match what's configured on the corresponding clients in Keycloak. To rotate a value:
- Edit the
boltmcp-oidcSecret (kubectl edit secret boltmcp-oidc -n boltmcp, or re-apply via your secrets manager) so the new value is base64-encoded under the right key (web-client-secret,mcp-server-client-secret,mcp-client-client-secret). - Update the same value on the matching client in the Keycloak admin console.
- Restart deployments so they pick up the new value (Kubernetes does not auto-restart pods on Secret changes):
kubectl rollout restart -n boltmcp deployment/boltmcp-web
kubectl rollout restart -n boltmcp deployment/boltmcp-playground
kubectl rollout restart -n boltmcp deployment/boltmcp-mcp-serverRedirect Loop
Check that client redirect URIs in Keycloak match the web/playground URLs. The redirect URI must include the full path pattern (e.g. https://web.boltmcp.example.com/*).
Certificate Issues
Certificate Stuck in False State
kubectl describe certificate boltmcp-tls -n boltmcp
kubectl get challenges -n boltmcpCommon causes:
- DNS not propagated — verify with
nslookup web.boltmcp.example.com - HTTP-01 challenge failed — ensure NGINX ingress is running and accessible
- Rate limited — use the staging ClusterIssuer for testing
Large Header Errors
If Keycloak produces "upstream sent too big header" errors, increase the buffer:
annotations:
nginx.ingress.kubernetes.io/proxy-buffer-size: "256k"Database lost+found Error
If the database pod logs show:
initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
initdb: detail: It contains a lost+found directoryThe PVC must be recreated:
helm uninstall boltmcp -n boltmcp
kubectl delete pvc data-boltmcp-database-0 -n boltmcp
helm install boltmcp \
oci://europe-west2-docker.pkg.dev/boltmcp-platform/boltmcp-alpha/charts/boltmcp \
--version ${BOLTMCP_VERSION} \
-n boltmcp \
-f values-prod.yamlDiagnostic Commands
# Pod status
kubectl get pods -n boltmcp
# Pod logs
kubectl logs -n boltmcp <pod-name>
# Pod events and details
kubectl describe pod -n boltmcp <pod-name>
# Services and endpoints
kubectl get svc -n boltmcp
kubectl get endpoints -n boltmcp
# Secrets
kubectl get secrets -n boltmcp
# Helm release status
helm list -n boltmcp
helm status boltmcp -n boltmcp
# Certificate status (if using Ingress)
kubectl get certificates -n boltmcp
kubectl get challenges -n boltmcp
# Ingress status
kubectl get ingress -n boltmcp
# NGINX Ingress logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx