# NPMplus UI — ApiError 400 runbook **Symptom:** NPMplus at https://192.168.11.167:81 shows "Welcome to NPMplus", "You are logged in as Administrator", but the browser console shows repeated **ApiError** with **code: 400** and empty or vague **message**. **Meaning:** The UI is logged in, but one or more API calls (e.g. loading proxy hosts, certificates, settings) return HTTP 400 Bad Request. The frontend (main.bundle.js) turns that into ApiError. --- ## 1. Identify which request returns 400 1. Open NPMplus in the browser: `https://192.168.11.167:81` 2. Open **Developer Tools** (F12) → **Network** tab 3. Enable "Preserve log" if available 4. Reload the page (or navigate to the tab that triggers the errors) 5. In the Network list, filter by **Fetch/XHR** (or look for requests to `/api/`) 6. Find any request with status **400** (red). Click it and check: - **Request URL** (e.g. `https://192.168.11.167:81/api/nginx/proxy-hosts`) - **Response** body (often JSON with an error message or validation detail) Note the exact URL and response; that tells you which backend endpoint is failing. --- ## 2. Test the same endpoint from the command line From a machine that can reach NPMplus (e.g. on the same LAN), with `NPM_EMAIL` and `NPM_PASSWORD` set (e.g. from `.env`): ```bash cd /path/to/proxmox source .env 2>/dev/null || true NPM_URL="${NPM_URL:-https://192.168.11.167:81}" # Login and get token TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \ -H "Content-Type: application/json" \ -d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}") TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty') if [ -z "$TOKEN" ]; then echo "Login failed: $TOKEN_RESPONSE" exit 1 fi echo "Login OK" # Test endpoints the dashboard typically calls for path in "/api/nginx/proxy-hosts" "/api/nginx/certificates" "/api/nginx/access-lists"; do CODE=$(curl -s -k -o /tmp/npm_test_body -w "%{http_code}" -X GET "$NPM_URL$path" -H "Authorization: Bearer $TOKEN") echo "$path -> HTTP $CODE" [ "$CODE" != "200" ] && echo " Body: $(head -c 500 /tmp/npm_test_body)" done ``` - If **login** fails with 400: credentials or request body may be wrong. - If **proxy-hosts** or **certificates** returns 400: the backend may be rejecting the request or returning bad data (e.g. invalid record in DB). Check NPMplus logs. --- ## 3. NPMplus container logs From the Proxmox host that runs NPMplus (VMID 10233, typically 192.168.11.11): ```bash ssh root@192.168.11.11 "pct exec 10233 -- docker logs npmplus --tail 200 2>&1" ``` Or, if NPMplus runs without Docker inside the container: ```bash ssh root@192.168.11.11 "pct exec 10233 -- tail -200 /data/logs/*.log 2>/dev/null" ``` Look for lines containing "400", "Bad Request", or validation errors around the time you load the UI. --- ## 4. Quick fixes to try | Action | When it helps | |--------|----------------| | **Hard refresh / clear cache** | Cached frontend or bad session | | **Incognito window** | Extensions or cache affecting requests | | **Different browser** | Browser-specific behavior | | **Re-login** | Session or token format issue | | **Use .166 instead of .167** | If NPMplus is bound to .166 and .167 is a VIP, try `https://192.168.11.166:81` | --- ## 5. If one endpoint always returns 400 - **GET /api/nginx/proxy-hosts** or **/api/nginx/certificates** returning 400 can mean the backend has a record that fails validation when serialized. Options: restore from backup, or (if you have DB access) inspect and fix or remove the offending row. See [NPMPLUS_BACKUP_RESTORE.md](NPMPLUS_BACKUP_RESTORE.md). - **NPMplus version:** You are on 2.12.3+0a85402. Check release notes or issues for that version for known 400s on list endpoints. --- ## 6. Export config (full API test) Running the full export script exercises login + proxy-hosts + certificates: ```bash NPM_URL="https://192.168.11.167:81" bash scripts/verify/export-npmplus-config.sh ``` If this completes without error, the main GET APIs work from curl; the UI 400 may be a different endpoint or browser-specific. If it fails, the script output shows which step returned an error.