Repository navigation
Troubleshooting
Common errors and how to fix them.
pip install -r requirements.txt --user
# or
pip install -r requirements.txt --break-system-packagespip install anthropic>=0.40.0
# Make sure pip installs into the correct Python
python3 -m pip install -r requirements.txt# Check the env var
echo $ANTHROPIC_API_KEY
# If empty, set it first
export ANTHROPIC_API_KEY=sk-ant-...
# Or add it to .env
echo "ANTHROPIC_API_KEY=sk-ant-..." >> .env
# Or add it via the CLI
python -m pentestai
> llm addGroq free tier: 10,000 tokens/minute.
Add another model as a fallback:
> llm add # add Anthropic or Ollama
> llm routing on # enable routing for load balancing
# Start Ollama
ollama serve
# Or as a service (systemd)
systemctl start ollama
# Make sure the URL is correct in .env
OLLAMA_BASE_URL=http://localhost:11434
# Test
curl http://localhost:11434/api/tags# Debian/Ubuntu/Kali
sudo apt-get install nmap
# macOS
brew install nmap
# Or set the path manually in .env
NMAP_PATH=/usr/local/bin/nmapnmap requires a raw socket for some scan types.
# Option 1: run with sudo
sudo python -m pentestai
# Option 2: setuid (only once)
sudo chmod u+s $(which nmap)
# Option 3: use a scan that does not require a raw socket
# nmap will automatically fall back to a TCP connect scan# Debian/Ubuntu
sudo apt-get install gobuster
# macOS
brew install gobuster
# Or download the binary directly
# https://github.com/OJ/gobuster/releasessudo apt-get install sqlmap
# or
pip install sqlmap# Check whether Neo4j is running
docker ps | grep neo4j
# Start Neo4j
docker run -d -e NEO4J_AUTH=neo4j/pentestai \
-p 7474:7474 -p 7687:7687 neo4j:5-community
# Wait 30 seconds, then check health
curl http://localhost:7474
# PentestAI will fall back to SQLite if Neo4j is unavailable# Start Qdrant
docker run -d -p 6333:6333 qdrant/qdrant:latest
# Test
curl http://localhost:6333/healthz
# PentestAI will fall back to in-memory TF-IDF if Qdrant is unavailable# Check who is using the port
lsof -i :8080
# Kill the process or use another port
python -m pentestai --api --port 8081# Create a new API key
curl -X POST http://localhost:8080/api/v1/auth/keys \
-H "Content-Type: application/json" \
-d '{"name": "my-key"}'
# Use the key in the header
curl http://localhost:8080/api/v1/sessions \
-H "X-API-Key: psk_..."WebSocket requires a scan that is still running. Make sure:
- Create a scan first:
POST /api/v1/scans - Connect the WebSocket right after the scan starts
- A scan with
scan_type: "recon"runs long enough
# List all sessions
ls sessions/*.json
# In the CLI
> session listmkdir -p sessions logs reports/output
chmod 755 sessions logs reports/output# Check that the JSON file is valid
python3 -c "import json; json.load(open('sessions/abc123.json'))"
# If corrupted, delete it and create a new one
rm sessions/abc123.jsonAI analysis requires a configured LLM:
> llm # check LLM status
> report # generate with AI
> report quick # generate without AI (faster)
mkdir -p reports/output
chmod 755 reports/output# Make sure the Docker daemon is running
docker ps
# Build with verbose output
docker build --progress=plain -t pentestai .
# If there is a network issue (apt-get fails)
docker build --network=host -t pentestai .# Use host.docker.internal (macOS/Windows)
# or the host IP on Linux
ip addr show docker0 # usually 172.17.0.1
# In .env for Docker
OLLAMA_BASE_URL=http://172.17.0.1:11434# Wait longer
docker compose up -d
sleep 60
docker compose ps
# Or skip the health check
# Edit docker-compose.yml and remove the healthcheck sectionSymptoms: docker ps hangs for a long time then EOF, docker system df → retrieving disk usage: EOF, curl --unix-socket ~/.docker/run/docker.sock http://localhost/_ping times out.
The most common cause on macOS: host disk full. The Docker VM cannot write metadata, so the engine API returns EOF.
# 1. Diagnose
df -h /System/Volumes/Data
du -sh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
curl -s -m 3 --unix-socket ~/.docker/run/docker.sock http://localhost/_ping; echo " exit=$?"
# 2. If free disk < 5 GB: free some space first
docker builder prune -f # requires a healthy daemon
docker image prune -a
# 3. If the daemon no longer responds, force restart
docker desktop stop || pkill -9 -f 'Docker Desktop'
pkill -9 -f 'com.docker'; pkill -9 -f 'docker-sandbox'
open -a Docker
# 4. Wait until ready
until curl -s --unix-socket ~/.docker/run/docker.sock http://localhost/_ping; do sleep 5; doneIf it is still EOF after restart, reset the VM disk (deletes images/volumes): see DEPLOYMENT.md.
A frozen VM makes graceful shutdown time out. Force it:
pkill -9 -f 'Docker Desktop'
pkill -9 -f 'com.docker'
pkill -9 -f 'docker-sandbox'
# root helper (com.docker.vmnetd) may remain runningThe com.docker.vmnetd helper runs as root and is not the cause of the hang.
# 1. Make sure the compose file is valid
docker compose config --quiet
# 2. Check that the variables actually reach the container
docker compose exec -T pentestai sh -c 'env | sort | grep -E "ANTHROPIC|OPENAI|PENTESTAI_MODE|TEST_"'
# 3. If empty, make sure the service has env_file
grep -A5 'env_file' docker-compose.yml
# 4. Recreate the container (env_file is read at create time, not at restart)
docker compose up -d --force-recreate pentestaiCommon cause: the key really is empty in .env (OPENAI_API_KEY=), or an old compose file that only passes some variables through environment:.
# Check (should be "no .env in image")
docker run --rm --entrypoint sh pentestai:latest -c \
'ls -la /app/.env 2>/dev/null || echo "OK: no .env in image"'If the file is there: make sure .dockerignore contains .env, .env.*, *.env.local, then rebuild. Old images that already contain .env must be treated as leaked — rotate any API keys that were in them.
brew upgrade --cask docker-desktop and the built-in updater can stop at:
sudo: a terminal is required to read the password
Run brew upgrade --cask docker-desktop directly in an interactive Terminal, or install manually from the DMG (no sudo, because /Applications/Docker.app belongs to the user). Full steps: DEPLOYMENT.md.
# Monitor progress (do not use --quiet)
docker compose --profile msf build --no-cache --progress plain | tee /tmp/build.log
# The build cache can take 7+ GB — clean it up after a successful build
docker builder prune -f
# Rebuild using the cache (only COPY layers changed)
docker compose --profile msf build# Host install
pip install playwright
playwright install chromium
# Container: rebuild after changing requirements.txt
docker compose --profile msf build pentestai
# Verify inside the container (must print True)
docker compose exec -T pentestai python3 -c \
"from tools.browser import BrowserTool; print(BrowserTool().available)"report pdf prints a warning instead of failing the whole report when
Chromium is missing.
The validation gate requires reproducible evidence. A descriptive evidence string is not enough.
# 1. Capture traffic or run a verified PoC
poc
poc verify sqli http://target/login
# 2. Attach an evidence file (hash is recorded)
evidence attach <finding_id> proof.txt
# 3. Re-run the gate
validate
# 4. Operator override after manual verification
validate <finding_id>Validated findings appear in SARIF (report sarif) and can fail CI
(scripts/ci_gate.py --fail-on high). Candidates are reported separately.
- nmap with many ports is indeed slow, this is normal
- Use
reconinstead ofrecon deepfor a fast scan - Limit the port range: env
NMAP_FLAGS="-p 1-1000"
- Anthropic Claude: normally 2-10 seconds per request
- Use Groq for fast tasks (sub-second)
- Enable routing:
llm routing on
TF-IDF keeps all documents in memory. If there are very many documents:
# Set up Qdrant to offload to disk
docker run -d -p 6333:6333 qdrant/qdrant:latest
# QDRANT_URL=http://localhost:6333sudo apt install nodejs npm -y
cd reports && npm install docx- Check that Node.js is installed:
node --version - Check that
reports/node_modules/docxexists:ls reports/node_modules/docx - Run it manually:
node reports/generate_docx.js(without args to see the error)
PentestAI> scope add 10.0.0.0/8
PentestAI> scope show
To find something outside the scope:
PentestAI> expand 192.168.1.5 "trust relationship found"
# Contact the client → scope approve <ref>
The client brief states no brute force. If you want to override (with client permission):
PentestAI> brief
# See the active rules
There is no bypass — this is by design to protect the engagement.
Check that the target is set:
PentestAI> session
PentestAI> target 10.0.0.1
PentestAI> orchestrate
Normal if there is no HTTP service in the session. Run recon first:
PentestAI> recon
PentestAI> orchestrate
Use --seq for debugging:
PentestAI> orchestrate 10.0.0.1 --seq
The plugin marketplace needs internet. Without internet, only local plugins are available:
PentestAI> marketplace installed
PentestAI> plugin list
The downloaded plugin differs from the published one. Do not install it — it could be dangerous. Report it to that plugin's issue tracker.