Troubleshooting¶
Audience: IT administrators operating Sentari in their environment
This guide covers the most common issues encountered when running Sentari. Each section follows a consistent structure: symptom, possible causes, and step-by-step resolution.
For issues not covered here, see Getting Help before contacting support.
Table of Contents¶
- Agent Issues
- Dashboard and Authentication Issues
- CVE Correlation Issues
- Alert Issues
- Performance Issues
- Deployment Issues
- Getting Help
1. Agent Issues¶
1.1 Agent won't enroll¶
Symptom: Running the agent returns an enrollment error, or the device does not appear in the Sentari dashboard after initial startup.
Cause: Wrong enrollment token¶
The agent's enrollment token must exactly match the value configured on the server.
Resolution:
Check the token in agent.conf:
[server]
url = https://sentari.example.com
Enrollment tokens are passed as a flag at first run:
sentari-agent-enterprise --config <path> --enroll-token "<your-enrollment-token>"
Verify the server-side token matches. On Docker Compose deployments, check your .env file:
grep SENTARI_ENROLLMENT_TOKEN /path/to/sentari/.env
On Kubernetes/OpenShift, check the Secret:
oc get secret sentari-api-env -o jsonpath='{.data.SENTARI_ENROLLMENT_TOKEN}' | base64 -d
The value must be identical (including case) on both sides.
Cause: Server unreachable¶
Resolution:
From the endpoint, verify the server URL resolves and accepts connections:
# Test DNS resolution
nslookup sentari.example.com
# Test TCP connectivity on port 443 (or your configured port)
curl -v --max-time 10 https://sentari.example.com/api/health
If the server is unreachable, check:
- Firewall rules allow outbound HTTPS (port 443) from the endpoint to the Sentari server
- Network routing between the endpoint and server subnet is in place
- Any host-based firewall on the endpoint (ufw, firewalld, Windows Defender Firewall) allows the connection
If your environment uses a forward proxy, configure it in agent.conf:
[proxy]
https_proxy = http://proxy.example.com:3128
no_proxy = localhost,127.0.0.1,internal.example.com
For authenticated proxies, set proxy_auth_user and place the password in a file referenced by proxy_auth_pass_file.
Cause: Certificate validation error¶
Resolution:
The agent performs mutual TLS verification. Check the CA certificate path in agent.conf:
[server]
ca_cert_file = /etc/sentari/ca.crt
Verify the file exists and is readable:
ls -l /etc/sentari/ca.crt
openssl x509 -noout -subject -issuer -enddate -in /etc/sentari/ca.crt
Ensure the certificate has not expired and matches the CA used by the Sentari server. The correct ca.crt is provided during initial enrollment — if the CA has been rotated since enrollment, re-enroll the agent.
Also verify your TLS version is not downgraded. Sentari requires TLS 1.2 or higher. Check that no proxy or network appliance is intercepting or downgrading TLS.
Cause: DNS resolution failure¶
Resolution:
The server hostname in agent.conf must resolve to the correct IP address from the endpoint:
nslookup sentari.example.com
dig sentari.example.com
If DNS resolution fails:
- Confirm the endpoint is using the correct DNS server (one that can resolve internal hostnames)
- Add a static entry to /etc/hosts (Linux/macOS) or C:\Windows\System32\drivers\etc\hosts (Windows) as a temporary workaround while resolving DNS
1.2 Agent enrolls but no scan data appears¶
Symptom: The device appears in the Sentari dashboard but shows no packages, or the last scan timestamp does not update.
Cause: Celery worker not running¶
Scan data is processed asynchronously by the Celery worker. If the worker is stopped, uploaded scans queue in Redis but are not written to the database.
Resolution — Docker Compose:
docker compose ps
docker compose logs --tail=50 sentari-worker
If the worker is stopped or in an error state:
docker compose restart sentari-worker
Resolution — OpenShift/Kubernetes:
oc get pods -l app=sentari-worker
oc logs deployment/sentari-worker --tail=50
oc rollout restart deployment/sentari-worker
Cause: Redis not running¶
The Celery worker depends on Redis as its message broker. If Redis is unhealthy, tasks will not be dispatched.
Resolution — Docker Compose:
docker compose ps sentari-redis
docker exec sentari-redis redis-cli ping
If ping does not return PONG, restart Redis:
docker compose restart sentari-redis
Resolution — OpenShift/Kubernetes:
oc get pods -l app=sentari-redis
oc logs deployment/sentari-redis --tail=50
Cause: Agent scan interval is too long¶
The default scan interval is 3600 seconds (1 hour). If the agent was recently enrolled, it may not have completed its first scan cycle yet.
Resolution:
Check the interval configured in agent.conf:
[scanner]
interval = 3600
To confirm the agent is scanning, check its log output. If logging.file is set in agent.conf, tail that file. Otherwise, check the service journal:
# Linux (systemd)
journalctl -u sentari-agent -n 50 --no-pager
# Windows
Get-EventLog -LogName Application -Source "SentariAgent" -Newest 20
A log line confirming a completed upload indicates the scan was submitted successfully and the issue is on the server side (Celery/Redis).
Cause: Proxy blocking agent-to-server communication¶
Resolution:
If the agent enrolled successfully but data is not arriving, the upload may be blocked by a proxy that permits the initial handshake but blocks larger payloads.
Verify the proxy configuration in agent.conf. Also confirm the proxy is not subject to a payload size limit that would reject scan uploads.
1.3 Agent shows "Offline" in the dashboard¶
Symptom: A device that previously reported successfully now shows an offline or stale status in the dashboard.
Cause: Network disruption¶
The agent is designed for intermittent connectivity. It queues scans locally in an SQLite cache and uploads them automatically when the connection is restored. No data is lost during a network outage.
Resolution:
Verify that the network path between the endpoint and the Sentari server is restored. Once the connection is available, the agent will upload queued scans without any manual intervention.
Cause: Agent process stopped¶
Resolution — Linux (systemd):
systemctl status sentari-agent
systemctl start sentari-agent
Resolution — Windows (Task Manager / Services):
Open services.msc, locate "Sentari Agent", and start the service. Or use PowerShell:
Start-Service -Name "SentariAgent"
Get-Service -Name "SentariAgent"
To configure automatic restart after failure, verify the service recovery options in the Windows installer were applied correctly (the provided install.ps1 sets these by default).
Cause: Endpoint clock skew¶
mTLS certificate validation requires the endpoint clock to be within a few minutes of the server clock. A large clock skew causes certificate validation to fail, preventing the agent from uploading.
Resolution:
Check the time difference between the endpoint and the server:
# Linux
timedatectl status
date
# Windows
w32tm /query /status
Ensure NTP synchronization is active. On Linux:
systemctl status systemd-timesyncd
timedatectl set-ntp true
On Windows:
w32tm /resync /force
2. Dashboard and Authentication Issues¶
2.1 Cannot log in¶
Symptom: The login page returns an error, an incorrect credentials message, or a timeout.
Cause: Wrong credentials¶
Resolution:
If the bootstrap admin password is unknown, it can be reset by re-setting the SENTARI_BOOTSTRAP_ADMIN_PASSWORD environment variable and restarting the API container. This only creates the admin user if no users exist; if users are already present, use a database-level password reset instead.
To reset via the database directly (Docker Compose):
# Connect to the database
docker exec -it sentari-db psql -U sentari -d sentari
-- Generate a new bcrypt hash first (use a Python one-liner or an online tool)
-- Then update the user record
UPDATE users SET hashed_password = '<new-bcrypt-hash>' WHERE email = 'admin@example.com';
\q
Cause: Stale browser session¶
JWT access tokens expire after 15 minutes. Refresh tokens expire after 8 hours. If both have expired, the browser session storage retains an invalid token state.
Resolution:
Clear the browser session storage and reload the page:
- Open browser Developer Tools (F12)
- Navigate to Application → Session Storage
- Clear all entries for the Sentari origin
- Reload the page and log in again
Alternatively, open a new private/incognito window.
Cause: LDAP server unreachable¶
When a user's account uses LDAP authentication, login is proxied to the LDAP server. If the LDAP server is unreachable, the API returns HTTP 503.
Resolution:
Verify the LDAP URL configured on the server:
# Docker Compose — check the running environment
docker exec sentari-api env | grep SENTARI_LDAP
Test connectivity to the LDAP server from the API container:
docker exec sentari-api curl -v ldap://ldap.example.com:389
Check the API logs for LDAP-specific error messages:
docker compose logs --tail=50 sentari-api | grep -i ldap
On OpenShift:
oc logs deployment/sentari-api --tail=50 | grep -i ldap
Ensure the values of SENTARI_LDAP_URL, SENTARI_LDAP_BASE_DN, SENTARI_LDAP_BIND_DN, and SENTARI_LDAP_BIND_PASSWORD are correct in your environment configuration.
Cause: OIDC misconfiguration¶
If OIDC/SSO is enabled (Keycloak, Azure Entra ID, etc.) and the SSO login button fails, the issue is typically a mismatch in the OIDC configuration.
Resolution:
Check the three critical values in your server environment:
| Variable | Example value |
|---|---|
SENTARI_OIDC_ISSUER_URL |
https://login.microsoftonline.com/{tenant}/v2.0 |
SENTARI_OIDC_CLIENT_ID |
Your application registration client ID |
SENTARI_OIDC_CLIENT_SECRET |
Your application registration client secret |
Verify that the redirect URI registered in your identity provider exactly matches the Sentari server URL (e.g. https://sentari.example.com/api/v1/oidc/callback). Any trailing slash or protocol mismatch will cause the redirect to fail.
Check the API logs after a failed SSO attempt for the specific OIDC error message.
2.2 Dashboard shows no data¶
Symptom: The dashboard loads but all widgets show zero counts or empty tables.
Cause: No agents enrolled¶
Resolution:
Navigate to the Devices page. If no devices are listed, no agents have completed enrollment. Follow the Agent Install guide to enroll endpoints.
Cause: Database connection failure¶
If the API cannot reach the database, it returns errors that appear as empty dashboard widgets without an explicit error message.
Resolution — Docker Compose:
docker compose ps sentari-db
docker exec sentari-db pg_isready -U sentari
docker compose logs --tail=30 sentari-api | grep -i "database\|sqlalchemy\|psycopg"
If the database container is healthy but the API cannot connect, verify the SENTARI_DATABASE_URL environment variable is correctly set.
2.3 Dashboard returns 403 Forbidden¶
Symptom: Certain pages or actions return a 403 error.
Cause: Insufficient role¶
Sentari uses role-based access control. The roles, in ascending order of privilege, are: viewer, analyst, admin, owner. Some pages and actions require a minimum role.
| Feature | Minimum role |
|---|---|
| View inventory, devices | viewer |
| View CVE findings, compliance reports | analyst |
| Acknowledge/suppress alerts | analyst |
| Manage policy rules | admin |
| Manage users, configuration | admin |
Resolution:
Ask an admin to verify and update the user's role in the Users page (Settings → Users).
Cause: Rate limited¶
The login endpoint enforces a limit of 5 attempts per IP address per 60 seconds. Exceeding this returns HTTP 429 with a Retry-After header.
Resolution:
Wait for the duration specified in the Retry-After response header, then retry. If this is triggered by a legitimate automation script, reduce the request rate or use a service account with a long-lived API token.
3. CVE Correlation Issues¶
3.1 No CVE findings appear¶
Symptom: The CVE page shows an empty table even though packages are present in the inventory.
Cause: Celery worker or beat scheduler not running¶
CVE correlation runs as an asynchronous Celery task in the worker container (not the API), triggered automatically after each agent scan upload. Correlation does not query OSV live per request: a daily feed sync (Celery beat, 02:00 UTC) populates a local, ecosystem-keyed CVE cache, and each scan is then correlated against that cache offline. If either the worker or the beat scheduler is not running, the cache is never populated and no findings appear.
Resolution — Docker Compose:
# Check all background services
docker compose ps
# Inspect worker logs
docker compose logs --tail=50 sentari-worker
# Inspect beat scheduler logs
docker compose logs --tail=50 sentari-beat
Restart any stopped service:
docker compose restart sentari-worker sentari-beat
Resolution — OpenShift/Kubernetes:
oc get pods -l 'app in (sentari-worker, sentari-beat)'
oc logs deployment/sentari-worker --tail=50
oc logs deployment/sentari-beat --tail=50
Cause: No CVE feeds configured¶
In air-gapped deployments, the server cannot reach the OSV API. You must supply an offline bundle. The feed sync that ingests the bundle runs in the worker container, so the bundle path must be accessible there.
Resolution:
In the dashboard, navigate to Settings → CVE and verify the "OSV Bundle Path" field is set to a path accessible from inside the worker container (e.g. /data/osv-bundle.ndjson). The bundle must be mounted into the worker container and the path must match exactly.
To trigger a manual sync after updating the path, click "Trigger CVE Sync" in the Settings page, or run the sync task in the worker container:
docker exec sentari-worker python -c "
from server.tasks.cve import sync_feeds
sync_feeds.delay()
print('CVE sync triggered')
"
Cause: Proxy blocking outbound CVE feed requests¶
In internet-connected deployments, the worker fetches feeds from api.osv.dev (OSV) and optionally services.nvd.nist.gov (NVD) during the scheduled sync.
Resolution:
Ensure your proxy is configured on the server. In your .env file:
SENTARI_HTTPS_PROXY=http://proxy.example.com:3128
SENTARI_NO_PROXY=sentari-db,sentari-redis,localhost,127.0.0.1
Test outbound connectivity from the worker container:
docker exec sentari-worker curl -v --max-time 10 https://api.osv.dev/v1/query
Cause: Packages have no known CVEs¶
If the above checks pass, the empty result may be correct. Not all packages have published CVE records. Scan results for packages with no CVE matches are expected to show no findings.
3.2 CVE sync fails¶
Symptom: The CVE sync task appears in logs but completes with errors. CVE data is stale or missing.
Cause: OSV API unreachable (internet-connected deployments)¶
Resolution:
Confirm port 443 outbound to api.osv.dev is allowed through your perimeter firewall. The feed sync runs in the worker container, so test from there:
docker exec sentari-worker curl -v --max-time 15 https://api.osv.dev/v1/query \
-H "Content-Type: application/json" \
-d '{"package": {"name": "requests", "ecosystem": "PyPI"}}'
A successful response returns a JSON object. A timeout or connection refused indicates a firewall block.
Cause: NVD API rate limited¶
The NVD public API enforces rate limits on unauthenticated requests.
Resolution:
Add an NVD API key in Settings → CVE → NVD API Key. With an API key, the rate limit is significantly higher. Register for a free key at https://nvd.nist.gov/developers/request-an-api-key.
Cause: Offline bundle path incorrect¶
Resolution:
Verify the path configured in Settings → CVE → OSV Bundle Path exists and is accessible inside the worker container:
docker exec sentari-worker ls -lh /data/osv-bundle.ndjson
If the file is not found, ensure the volume mount is correctly configured and the file has been placed at the expected path on the host.
3.3 Runtime EOL data is missing or stale¶
Symptom: The Runtime / EOL views show no end-of-life status for Python, Node, or JDK versions, or the data has not refreshed.
Cause: Runtime-EOL feed sync has not run¶
Runtime end-of-life status is populated by a daily Celery beat task (runtime-eol-sync, 03:00 UTC) running in the worker. It fetches endoflife.date data online, or reads an NDJSON bundle in air-gap deployments.
Resolution:
Confirm the worker and beat scheduler are running (see §3.1), then inspect the worker logs for the task, or trigger it manually:
docker compose logs --tail=50 sentari-worker | grep -i runtime_eol
docker exec sentari-worker python -c "
from server.tasks.runtime_eol import sync_runtime_eol_feeds
sync_runtime_eol_feeds.delay()
print('Runtime-EOL sync triggered')
"
3.4 No CVE findings for OS / distro packages¶
Symptom: Python-package CVEs appear, but Debian/RPM (system_deb / system_rpm) packages show none.
Cause: Distro feed not synced or release not detected¶
Distro CVE correlation is release-keyed: it requires the OS distro feeds in the local cache (synced by the same cve-feed-sync task) and an os_release / source_package on the scan. If the agent did not report the OS release, server-side distro correlation is skipped.
Resolution:
Confirm the worker has run a feed sync (§3.1), and verify recent scans from affected devices carry OS-release metadata. If the device's agent predates distro reporting, upgrade the agent.
4. Alert Issues¶
4.1 Email alerts not sending¶
Symptom: Critical or high-severity CVE findings or policy violations are detected, but no email is received.
Cause: SMTP not configured¶
Resolution:
In the dashboard, navigate to Settings → SMTP and verify all required fields are populated:
| Field | Example |
|---|---|
| SMTP Host | smtp.example.com |
| SMTP Port | 587 (STARTTLS) or 465 (implicit TLS) |
| From address | sentari-alerts@example.com |
| To address | security-team@example.com |
| Username | SMTP account username |
| Password | SMTP account password |
Cause: SMTP authentication failure¶
Resolution:
Check the Celery worker logs for authentication errors after a CVE or policy alert is generated:
docker compose logs --tail=100 sentari-worker | grep -i "smtp\|email\|alert"
Common errors and solutions:
| Error | Resolution |
|---|---|
535 Authentication failed |
Verify username and password; check if the account requires an app-specific password |
534 Please log in via your web browser |
The account requires OAuth or has 2FA enabled — use a dedicated service account or app password |
Connection refused |
Verify the SMTP host and port are correct and reachable from the worker container |
Cause: SMTP TLS configuration mismatch¶
Sentari uses STARTTLS by default. If your SMTP server requires implicit TLS (e.g. port 465), this must be configured appropriately.
Resolution:
Test SMTP connectivity from the worker container:
# Test STARTTLS on port 587
docker exec sentari-worker python -c "
import smtplib
with smtplib.SMTP('smtp.example.com', 587, timeout=10) as s:
s.ehlo()
s.starttls()
print('STARTTLS OK')
"
If your provider uses implicit TLS on port 465, verify that SMTP_USE_TLS is set correctly in Settings → SMTP.
Cause: Celery worker not running¶
Email alerts are dispatched asynchronously by the Celery worker. If the worker is stopped, emails are queued but not sent.
Resolution:
See 1.2 — Celery worker not running for restart instructions.
Cause: Alert severity below email threshold¶
Email alerts are only generated for critical and high severity findings. Medium and low severity findings generate in-dashboard alerts only.
Resolution:
This is expected behavior. Review in-dashboard alerts on the Alerts page for medium and low severity items.
4.2 SIEM webhook not firing¶
Symptom: Alerts are visible in the dashboard but are not being delivered to your SIEM platform.
Cause: Webhook URL not configured¶
Resolution:
Navigate to Settings → SIEM and verify the webhook URL is set. The URL must be reachable from the Sentari server (not the agent endpoints).
Cause: Webhook endpoint unreachable¶
Resolution:
Test connectivity to the SIEM webhook URL from the API or worker container:
docker exec sentari-worker curl -v --max-time 10 \
-X POST https://siem.example.com/webhook \
-H "Content-Type: application/json" \
-d '{"test": true}'
If the connection fails, check firewall rules, proxy configuration, and whether the SIEM URL is included in the NO_PROXY bypass list or requires the proxy.
Cause: Delivery errors in Celery worker¶
Resolution:
The webhook delivery task retries up to 5 times with exponential backoff. Check the worker logs for delivery attempts and error details:
docker compose logs --tail=100 sentari-worker | grep -i "webhook\|siem\|deliver"
On OpenShift:
oc logs deployment/sentari-worker --tail=100 | grep -i "webhook\|siem\|deliver"
5. Performance Issues¶
5.1 Dashboard slow to load¶
Symptom: Dashboard pages take more than a few seconds to render, or queries time out.
Cause: Database needs maintenance¶
TimescaleDB accumulates statistics over time. Running VACUUM ANALYZE refreshes query planner statistics and reclaims space from deleted rows.
Resolution — Docker Compose:
docker exec sentari-db psql -U sentari -d sentari -c "VACUUM ANALYZE;"
Resolution — OpenShift/Kubernetes:
oc exec deployment/sentari-db -- psql -U sentari -d sentari -c "VACUUM ANALYZE;"
Schedule this as a periodic maintenance task (weekly is sufficient for most deployments).
Cause: Large number of unacknowledged alerts¶
The Alerts page query becomes slower as the number of open alerts grows. Acknowledging or suppressing resolved alerts keeps query performance healthy.
Resolution:
On the Alerts page, use the bulk acknowledge feature to close resolved alerts. Alternatively, suppress alerts for packages or devices that are known exceptions.
Cause: Large scan history volume¶
TimescaleDB stores time-series scan data. Without a retention policy, this grows indefinitely.
Resolution:
Add a retention policy to limit how long raw scan history is kept. Connect to the database and apply a policy (adjust the interval to match your compliance requirements):
docker exec sentari-db psql -U sentari -d sentari -c "
SELECT add_retention_policy('scan_results', INTERVAL '365 days');
"
This removes scan data older than 365 days automatically. Adjust the interval based on your organization's data retention policy.
5.2 High disk usage¶
Symptom: The host running Docker Compose or the persistent volume claim in Kubernetes is approaching capacity.
Cause: Growing TimescaleDB scan history¶
Resolution:
Check the current size of the TimescaleDB data volume:
docker exec sentari-db psql -U sentari -d sentari -c "
SELECT hypertable_name,
pg_size_pretty(hypertable_size(format('%I', hypertable_name)::regclass)) AS size
FROM timescaledb_information.hypertables;
"
Apply a data retention policy (see 5.1 — Large scan history volume).
Cause: Docker container log files growing unbounded¶
Container logs accumulate on the Docker host without rotation by default.
Resolution:
Add log rotation to the Docker daemon configuration at /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
}
}
Restart the Docker daemon to apply:
systemctl restart docker
Cause: Redis memory growth¶
Redis holds Celery task queues and results. Stale results accumulate if tasks complete but are never consumed.
Resolution:
Check Redis memory usage:
docker exec sentari-redis redis-cli info memory | grep used_memory_human
To clear all stale Celery task results (this does not affect pending tasks or cached data):
docker exec sentari-redis redis-cli --no-auth-warning -a "${REDIS_PASSWORD}" FLUSHDB
Note: Only flush Redis if you are certain no tasks are currently in-flight. Restart all Celery services immediately after flushing.
6. Deployment Issues¶
6.1 Container won't start¶
Symptom: docker compose up starts services but one or more exit immediately or fail their health checks.
Cause: Missing required environment variables¶
Resolution:
Compare your .env file against .env.example:
diff .env .env.example
The following variables are required and have no safe defaults:
| Variable | Purpose |
|---|---|
SENTARI_SECRET_KEY |
JWT signing key — must be a strong random string |
POSTGRES_PASSWORD |
TimescaleDB password |
REDIS_PASSWORD |
Redis authentication password |
Generate a suitable secret key:
python3 -c "import secrets; print(secrets.token_hex(32))"
Cause: Port 8000 already in use¶
Resolution:
Check which process is using port 8000:
ss -tlnp | grep 8000
# or
lsof -i :8000
Either stop the conflicting process or change the Sentari port binding in docker-compose.yml:
ports:
- "8080:8000" # Expose on host port 8080 instead
Cause: Database migration failure¶
Alembic runs migrations automatically on startup. If a migration fails, the API container exits.
Resolution:
Inspect the API container logs immediately after startup:
docker compose logs sentari-api | grep -i "alembic\|migration\|error"
Common causes:
- The database is not yet ready when the API starts (transient — fixed by the depends_on health check, but may occur on first deployment if the DB takes longer than usual to initialize)
- A previous failed migration left the schema in a partial state
To re-run migrations manually:
docker exec sentari-api alembic upgrade head
6.2 OpenShift pod stuck in CrashLoopBackOff¶
Symptom: One or more Sentari pods repeatedly restart on OpenShift.
Resolution — Check pod logs¶
oc logs <pod-name> --previous
# or for a deployment
oc logs deployment/sentari-api --previous
The --previous flag shows logs from the last crashed container instance.
Cause: Security Context Constraints (SCC) violation¶
OpenShift enforces SCCs that may conflict with the container's SecurityContext.
Resolution:
Check for SCC-related events:
oc get events --sort-by='.lastTimestamp' | grep -i "scc\|security\|privilege"
Sentari's containers are configured with:
- allowPrivilegeEscalation: false
- readOnlyRootFilesystem: true
- capabilities.drop: [ALL]
- seccompProfile: RuntimeDefault
These settings are compatible with the restricted SCC. If your cluster uses a more restrictive custom SCC, consult your cluster administrator to grant the restricted SCC to the Sentari service account:
oc adm policy add-scc-to-serviceaccount restricted -z sentari -n <namespace>
Cause: Persistent Volume Claim not bound¶
If a PVC remains in Pending state, pods that depend on it will not start.
Resolution:
oc get pvc -n <namespace>
oc describe pvc <pvc-name> -n <namespace>
The most common cause is that the requested StorageClass does not exist or has no available provisioner. Check available storage classes:
oc get storageclass
Update the Helm values to use a storage class available in your cluster:
persistence:
storageClass: "your-storage-class-name"
6.3 License validation fails¶
Symptom: The API logs show license validation errors. The dashboard may display a warning banner.
Cause: License server unreachable¶
Sentari performs periodic license validation against license.sentari.dev. In air-gapped or restrictive network environments, this connection may be blocked.
Resolution:
Allow outbound HTTPS (port 443) to license.sentari.dev from the API server. If a proxy is required, ensure it is configured via SENTARI_HTTPS_PROXY.
Test connectivity:
docker exec sentari-api curl -v --max-time 10 https://license.sentari.dev/
Cause: Proxy not configured for license validation¶
Resolution:
Add the proxy configuration to your .env file. The license validation uses the same proxy settings as CVE feed requests.
Cause: Invalid license key¶
Resolution:
Verify the license key in your .env file matches the key issued by Sentari:
grep SENTARI_LICENSE_KEY /path/to/sentari/.env
If the key is correct and validation still fails, contact Sentari support with your license key and the error message from the API logs.
Grace period behavior¶
If license validation cannot reach the license server, Sentari continues operating normally for the duration of the license's max_offline_days claim (default: 1 day; up to 365 days on the air-gap tier). This covers planned network outages and brief connectivity disruptions. The dashboard displays a warning banner during this period. Once the offline tolerance window expires, some features may be restricted — contact support before that point. For details on offline tolerance tiers, see Licensing.
7. Getting Help¶
Before contacting support, collect the following diagnostic information. This significantly reduces resolution time.
Check service health¶
Docker Compose:
# Overall status
docker compose ps
# Database connectivity
docker exec sentari-db pg_isready -U sentari
# Redis connectivity
docker exec sentari-redis redis-cli ping
# API health endpoint
curl -sf http://localhost:8000/api/health
OpenShift/Kubernetes:
oc get pods -n <namespace>
oc get events --sort-by='.lastTimestamp' -n <namespace>
Collect logs¶
Docker Compose — collect the last 100 lines from all Sentari services:
docker compose logs --tail=100 sentari-api sentari-worker sentari-beat > sentari-logs.txt 2>&1
OpenShift/Kubernetes:
for deployment in sentari-api sentari-worker sentari-beat; do
echo "=== $deployment ===" >> sentari-logs.txt
oc logs deployment/$deployment --tail=100 >> sentari-logs.txt 2>&1
done
Agent logs:
Check the [logging] section of agent.conf for the configured log file path. If no file is configured, the agent writes to stderr:
# Linux — if managed by systemd
journalctl -u sentari-agent -n 100 --no-pager > agent-logs.txt
# Windows — from the service log file path in agent.conf
Enable debug logging (temporary)¶
To get more detailed logs from the server during an active investigation, set SENTARI_LOG_LEVEL=debug in your environment and restart the API container:
# Docker Compose
docker compose down && SENTARI_LOG_LEVEL=debug docker compose up -d
# Kubernetes / OpenShift — patch the deployment
oc set env deployment/sentari-api SENTARI_LOG_LEVEL=debug
Revert to the default log level after the investigation by removing the variable or setting SENTARI_LOG_LEVEL=info.
Note:
SENTARI_LOG_LEVEL=debugonly raises log verbosity — it does not change any security behaviour. Leave it set only for the duration of the investigation.
Contact support¶
Send the collected logs and a description of the issue to your Sentari support contact. Include:
- The version of Sentari deployed (visible in the dashboard footer or via
docker compose images) - The deployment method (Docker Compose, Kubernetes, OpenShift)
- The operating system and version of the server host
- A description of when the issue started and any recent changes to the environment
- The
sentari-logs.txtandagent-logs.txtfiles collected above