Files
proxmox/docs/04-configuration/NPMPLUS_UI_APIERROR_400_RUNBOOK.md
defiQUG e4c9dda0fd
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
chore: update submodule references and documentation
- Marked submodules ai-mcp-pmm-controller, explorer-monorepo, and smom-dbis-138 as dirty to reflect recent changes.
- Updated documentation to clarify operator script usage, including dotenv loading and task execution instructions.
- Enhanced the README and various index files to provide clearer navigation and task completion guidance.

Made-with: Cursor
2026-03-04 02:03:08 -08:00

4.1 KiB

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):

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):

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:

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 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:

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.