-
Notifications
You must be signed in to change notification settings - Fork 12
DashboardConnectivity
Covers connecting a separately-hosted dashboard app (e.g.
NeoEssentials-Dashboard, the Laravel app) to the mod's built-in API, diagnosing "the connection isn't establishing", and thewebDashboard.modeconfig option ("external"vs. the mod's own bundled"internal"UI).
The mod's dashboard has always been two things bundled together:
- A REST API under
/api/*(moderation, players, economy, permissions, etc.) - A static UI served at
/— the mod's own bundled HTML/JS/CSS dashboard frontend
Until now there was no way to run just the API without the mod also trying (and, in most dev/
production setups, failing) to serve its own bundled UI — every boot logged
Dashboard resources NOT found - /webdashboard/index.html is null! even on servers that only
ever use an external dashboard app and never load http://<server>:8080/ directly.
| Value | Behavior |
|---|---|
"external" (default) |
Serves only /api/*. The / static-file route is never registered. Use this when a separate app (Laravel NeoEssentials-Dashboard) is the only thing that ever talks to this port — the shipped config template sets this explicitly. |
"internal" |
Serves the mod's own bundled dashboard UI at / and the API at /api/* — no separate app to install. As of build.13 this bundled UI is feature-complete (all 13 pages, matching the external app) — use this if you'd rather not run/maintain a separate Laravel process. |
"both" |
Explicit alias for "internal" — same behavior, for config clarity when you deliberately use the built-in UI and point an external app at the same API at the same time. |
Switching to "internal"/"both" requires the mod's Gradle build to have bundled the dashboard
UI assets (webdashboard-ui/ → build/generated/dashboardUiResources/, wired into
processResources — this happens automatically for anyone building from source; official
released jars already include it).
Requires a restart to take effect (same as every other config toggle — see the "reload doesn't add/remove commands" limitation documented elsewhere).
Unauthenticated, always registered regardless of mode. Returns:
{"success": true, "mod": "neoessentials", "mode": "internal"}Use this to answer "can I reach the mod's HTTP port at all" as a separate question from "is the dashboard actually paired/authenticated" — the two failure modes look identical from the outside (both just time out or error) but need completely different fixes.
curl http://<mod-server-ip>:8080/api/ping- Connection refused / timeout → network problem (see checklist below), not a mod bug.
- 200 with the JSON above → the mod's API is reachable; if the dashboard app still can't connect, the problem is in the pairing/API key, not connectivity — see API System → Pairing.
The most common reason "the connection isn't establishing" used to come up at all: /dashboard start/stop/status/restart were dead code — the class existed and compiled, but was never
actually registered with the command dispatcher, so they were literally unknown commands. Combined
with webDashboard.autoStart: false, this meant the dashboard's HTTP server could simply never be
running at all, with no in-game way to diagnose or fix it — no amount of correct MC_API_URL/
service-account config on the external dashboard's side would help, since nothing was listening on
the port in the first place. Fixed long since; only relevant if you're troubleshooting a very old build.
Action item for anyone hitting this: check /dashboard status in-game (after restarting to
pick up the fix) — if it says stopped, either set autoStart: true or run /dashboard start.
Work through these in order — each rules out one layer:
-
Is the mod's dashboard actually running?
/dashboard statusin-game. If stopped:/dashboard start, or setwebDashboard.enabled/modules.webDashboardEnabled/webDashboard.autoStarttotrueand restart. -
Can you reach the port from the SAME machine the Minecraft server is on?
curl http://127.0.0.1:8080/api/pingon the Minecraft server's own machine. If this fails, it's not a network issue — go back to step 1, or checkwebDashboard.portfor a typo/conflict with another service. -
Can you reach the port from the machine the Laravel app runs on?
curl http://<minecraft-server-ip>:8080/api/pingfrom the Laravel app's machine (or whereverMC_API_URLpoints). If this fails but step 2 succeeded, it's a network-layer problem:-
webDashboard.bindAddress— must be0.0.0.0(all interfaces) if the Laravel app is on a different machine;127.0.0.1only accepts connections from the same machine. - Firewall on the Minecraft server's OS (Windows Firewall, ufw, etc.) — port 8080 (and 8081 for WebSocket) need an inbound allow rule.
- If the Minecraft server is behind NAT/a router (common for home-hosted servers), the port needs to be forwarded.
- Cloud/VPS firewall (AWS security group, DigitalOcean firewall, etc.) if hosted in the cloud.
- If accessed via a domain/reverse proxy, check that proxy's own routing/TLS config separately
—
/api/pingbypassing it entirely (hit the raw IP:port) isolates whether the proxy or the mod itself is the problem.
-
-
Is
MC_API_URLin the Laravel app's.envactually correct? Common mistake: leaving it ashttp://127.0.0.1:8080when the Minecraft server is on a different machine from where Laravel runs —127.0.0.1from Laravel's perspective means "the Laravel server itself", not the Minecraft server. Must be the Minecraft server's real reachable IP/hostname. -
Is the dashboard actually paired?
/api/pingsucceeding but the dashboard still can't call mutating endpoints means steps 1–4 are fine. Check:-
MC_SERVICE_API_KEYin the Laravel app's.envis actually populated — it's set automatically by running/dashboard pair "<dashboardUrl>" <code>(get the code from the dashboard's own Configuration page), never hand-typed. See API System → Pairing. - The paired key hasn't been revoked —
/apikey listin-game shows every key's status; if it's gone, re-pair. - The key's role is at least
MODERATORif the Laravel app needs to call mutating endpoints (ban/kick/economy adjust/etc.) —VIEWERis read-only. Role is set at pairing time via/apikey create's role (pairing itself always mints anADMINkey).
-
-
Is
storage.type/database connectivity a separate red herring? Not related to dashboard connectivity — don't confuse aClassNotFoundExceptionfrom the SQLite/MySQL storage backend (a dev-environment-only classloader limitation, see the Storage wiki page) with the dashboard's own HTTP connectivity. They're independent systems.
NeoEssentials ships three parallel dev branches, one per supported Minecraft-version line —
1.21.x (1.21.1–1.21.11), 26.1.x (pinned to 26.1–26.1.2), and 26.2.x (26.2) — kept in sync by
cherry-picking every feature/fix commit across all three as it lands, including all of the
dashboard/connectivity work described on this page. They share one build-number counter (a GitHub
Actions repo variable, BUILD_NUMBER — not a file committed to the branches) so a fix shipped on
all three lands under the same build number everywhere. Everything described on this page (the
webDashboard.mode config, /api/ping, the dashboard security/account-linking features) is
already live on all three branches.
Since this connectivity layer is plain Java (HttpExchange/HttpServer, no net.minecraft.*
types touched) and JSON config, it's historically been a low-risk, mechanical cherry-pick with no
exposure to the Minecraft-version API differences that trip up other cross-branch ports (e.g.
GameProfile/getProfileCache() → NameAndId/server.services().nameToIdCache(),
ClickType → ContainerInput) — worth knowing if you're deciding how to port a future change
here yourself. 26.1.x and 26.2.x do occasionally need a small API-shape adjustment for changes
in other parts of the mod (not this connectivity layer specifically) since Mojang's official
mappings rename things between Minecraft versions — see each branch's own README for its current
target version.
Back to Wiki Home