docs(crafty): "You are not invited" is an empty allowlist -- and it proves RakNet works
New operator observation: a Bedrock client got "Unable to connect / You are not invited to play on this server". That was put to me as evidence that NetherNet signalling is working, that the refusal may have come from Microsoft rather than our server, and that BDS players therefore never traverse crafty-l4-udp. Measured read-only at 21:56, all three are wrong. allow-list=true (server.properties line 37) allowlist.json == [] (3 bytes, mtime 20:51, never edited since create) online-mode=true transport=raknet (line 71; file mtime STILL 21:33:31) UDP 19132 bound (/proc/net/udp 00000000:4ABC, pid 47006) TCP 19132 ABSENT (no 4ABC in /proc/net/tcp or tcp6) bedrock_server pid 47006, same process since 21:34, never restarted 1. transport is still raknet -- nobody reverted it, the binary did not rewrite it (mtime unchanged, audit.log records no later edit, same pid). NetherNet is NOT in use and cannot be what served this client. 2. NetherNet could not have served it in principle: it signals over TCP on server-port, and there is no TCP 19132 listener in the pod at all. 3. So the refusal came from OUR server, over RakNet, over 19132/udp, through the VIP. The 19132-19134/UDP exposure is the opposite of inert -- it carried both the earlier pong and this refusal. 4. Cause is certain and trivial: allow-list=true with an empty allowlist.json refuses every player. The shipped how_to says so, and it keys on Xbox Gamertag. The requested log correlation cannot be done from disk: K3s-Bedrock's log_path in crafty.sqlite is the empty string and Dedicated_Server.txt is 0 bytes -- Crafty persists no BDS stdout at all, the console is panel-UI-only. commander.log 21:39-21:56 holds only homelab crash-detection and raknet_ping lines. That silence is evidence about Crafty's logging, not about the refusal's origin. Adds a README section on the join authorization model: the measured table, the proof the refusal is ours, the "console is not on disk" caveat, gamertag/XUID identity, and three operator routes (console `allowlist add`, edit-then-`allowlist reload`, or allow-list=false -- discouraged, since the game port is deliberately un-gated so the allowlist is the only join control). Notes allowlist.json is PVC state that resets to [] on a server recreate. Options table and human test 4 now check the allowlist before blaming the network. Ranking unchanged at the top: keep transport=raknet, add gamertags. Still zero manifest change. NetherNet would ADD work (TCP 19132 in crafty-l4-tcp and in crafty-allow-ingress, plus server-udp-ports) and admit not one extra player. Read-only throughout: allowlist.json, server.properties and the DB were read; no console command issued, no kubectl mutation, no flux reconcile. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
8697702d51
commit
cd2617e5b3
2 files changed
+207
-5
No files matched your search
@@ -5503,3 +5503,120 @@ not merge it.**
|
||||
then re-ping. The vendor default is `nethernet`, and the regression is silent.
|
||||
6. **If a second simultaneous player evicts the first**, that is the SNAT/UDP-conntrack theory becoming
|
||||
real; it needs its own measured investigation, not a guess.
|
||||
|
||||
## 2026-09-29 (later still) — "You are not invited": the join gate is an empty allowlist. RakNet is confirmed working *by the refusal itself*
|
||||
|
||||
A Bedrock client reported **"Unable to connect / You are not invited to play on this server"**. This was
|
||||
put to me as evidence that NetherNet signalling is working, that the refusal might have come from
|
||||
Microsoft rather than our server, and that BDS players therefore never traverse this repo's
|
||||
`crafty-l4-udp` path. **Measured, all three of those are wrong.** The refusal is ours, it came back over
|
||||
`19132/udp`, and it has a one-line cause.
|
||||
|
||||
### Measured 21:56 (read-only)
|
||||
|
||||
| Property / file | Value |
|
||||
|---|---|
|
||||
| `allow-list` | **`true`** (line 37 of `server.properties`) |
|
||||
| `allowlist.json` | **`[]`** — 3 bytes, mtime **20:51**, never edited since the server was created |
|
||||
| `online-mode` | `true` |
|
||||
| `transport` | **`raknet`** (line 71); `server.properties` mtime **still 21:33:31** |
|
||||
| UDP 19132 | bound — `/proc/net/udp` `00000000:4ABC`, pid 47006 |
|
||||
| **TCP 19132** | **absent** — `grep 4ABC /proc/net/tcp /proc/net/tcp6` → no match |
|
||||
| `bedrock_server` | pid **47006**, etime 21:58 — the *same* process since 21:34, never restarted |
|
||||
| `K3s-Bedrock.log_path` | **`''`** (empty string) in `crafty.sqlite`; `Dedicated_Server.txt` is **0 bytes** |
|
||||
|
||||
### What that settles
|
||||
|
||||
1. **`transport` is still `raknet`. Nobody reverted it and the binary did not rewrite it.** The file's
|
||||
mtime is unchanged from the operator's 21:33:31 edit, `audit.log` records no later edit, and pid
|
||||
47006 has been the same process since 21:34. **So NetherNet is NOT in use and cannot be what served
|
||||
this client.** The premise that "something is evidently set to nethernet" is refuted.
|
||||
2. **NetherNet could not have served it even in principle:** nethernet signals over a **TCP** socket on
|
||||
`server-port`, and there is **no TCP 19132 listener in the pod at all**. No signalling endpoint
|
||||
exists, and none is exposed by any Service.
|
||||
3. **Therefore the refusal came from our server, over RakNet, over `19132/udp`, through the VIP.** A
|
||||
refusal authored by the server requires the client to have reached the server; the only listener is
|
||||
the RakNet UDP socket. **The 19132-19134/UDP exposure is the opposite of inert — it is the path that
|
||||
carried both the earlier pong and this refusal.** *(Observed: the listeners, the missing TCP socket,
|
||||
`transport=raknet`, the process identity. Reasoned from those: that the refusal traversed that path.)*
|
||||
4. **The cause is trivial and certain: `allow-list=true` with `allowlist.json == []` refuses every
|
||||
player.** The shipped `bedrock_server_how_to.html` states it — *"If the `allow-list` property is
|
||||
enabled … the server will only allow selected users to connect. To allow a user to connect you need
|
||||
to know their Xbox Live Gamertag."* An empty array selects nobody. **This configuration cannot admit
|
||||
anyone, so the refusal needed no other explanation.**
|
||||
|
||||
### The correlation I was asked for, and why it cannot be done from disk
|
||||
|
||||
I was asked to correlate the client error against the BDS server log and `commander.log` at 21:40–22:00,
|
||||
on the basis that our log showing nothing would mean the refusal came from Microsoft. **That inference
|
||||
does not hold here, because there is no BDS log on disk to be silent.** ``K3s-Bedrock``'s `log_path` is
|
||||
the empty string and `Dedicated_Server.txt` is 0 bytes: **Crafty persists no Bedrock stdout anywhere on
|
||||
the PVC** — the console is panel-UI-only. `commander.log` 21:39–21:56 holds nothing but `homelab`
|
||||
crash-detection lines and `raknet_ping` chatter: no join, no gamertag, no XUID, no allowlist denial.
|
||||
That silence is evidence about Crafty's logging, **not** about the refusal's origin. **UNVERIFIED and
|
||||
only observable live in the panel console.** The point stands: absence of a log here is not absence of
|
||||
an event.
|
||||
|
||||
I also did **not** capture the player's packet (no `tcpdump`, no `cilium monitor`), so the flow's
|
||||
identity is inferred from the listener topology, not seen. What removes the doubt is that the
|
||||
configuration is *unconditionally* refusing: whichever path a client takes, `allow-list=true` plus `[]`
|
||||
denies it. The operator action is required either way.
|
||||
|
||||
### Correction to the earlier entry's loose end, now firmer
|
||||
|
||||
The previous entries left "who sent those 26 packets / 27660 bytes on the `19132/UDP` policy map"
|
||||
UNVERIFIED, and it stays UNVERIFIED — but note it was measured *before* 21:34, i.e. during the nethernet
|
||||
window when **no UDP listener existed**. Those packets are consistent with clients RakNet-pinging a port
|
||||
nothing was listening on. They should **not** be attributed to a successful Bedrock session, and equally
|
||||
should not now be re-attributed to this refused client, which arrived later.
|
||||
|
||||
### Ranking after this measurement — unchanged at the top
|
||||
|
||||
**Keep `transport=raknet`, add the players to the allowlist. Still zero manifest change.** The allowlist
|
||||
refusal is orthogonal to transport: it would refuse identically under NetherNet. Switching to NetherNet
|
||||
would *add* manifest work (TCP 19132 in `crafty-l4-tcp` **and** `crafty-allow-ingress`, plus
|
||||
`server-udp-ports` pinned and exposed) and would admit **not one extra player**. "Accept NetherNet" does
|
||||
**not** outrank the status quo on this evidence, because NetherNet is not what is working — RakNet is.
|
||||
Geyser stays at #2, reserve-only.
|
||||
|
||||
### What changed in this repo
|
||||
|
||||
`platform/crafty/README.md` — added *"You are not invited to play on this server — the join gate is the
|
||||
allowlist, not the network"*: the measured table, the proof that the refusal is ours and rode the UDP
|
||||
path, the "BDS console is not on disk" caveat, the gamertag/XUID identity model, the three operator
|
||||
routes (`allowlist add` in the console; edit-then-`allowlist reload`; or `allow-list=false`, discouraged
|
||||
because the game port is deliberately un-gated so the allowlist is the *only* join control), and a note
|
||||
that `allowlist.json` is PVC state that resets to `[]` on a server recreate. Updated the options table
|
||||
and human test 4 to put the allowlist check before blaming the network. **No manifest touched.**
|
||||
|
||||
### Still UNVERIFIED
|
||||
|
||||
- **No successful join.** Reachability and an authorization refusal are both proven; a completed login is
|
||||
not. Only a human with a client, after an allowlist entry, can close it.
|
||||
- **The exact client-side string was not observed by me** — it is the operator's report, and its mapping
|
||||
to the allowlist denial is **reasoned** from the vendor doc, not read out of a BDS log (there is none).
|
||||
- **Whether the client used Add-Server-by-IP or an Xbox/Friends route is unknown**, so a *concurrent*
|
||||
Xbox-side "not invited" cannot be fully excluded. It does not matter operationally: the allowlist must
|
||||
be fixed regardless, and after that a retry distinguishes the two immediately.
|
||||
- **The multi-player SNAT question** remains open and untested.
|
||||
- **Nothing was written.** `allowlist.json`, `server.properties` and the DB were read only; no
|
||||
`allowlist add` was issued, no console command sent, no `kubectl` mutation, no `flux reconcile`.
|
||||
|
||||
### Operator actions — revised, allowlist first
|
||||
|
||||
1. **Add each player's Xbox Gamertag to the allowlist.** Crafty → `K3s-Bedrock` → Console:
|
||||
`allowlist add <Gamertag>` (quote if it contains a space). Takes effect immediately, no restart.
|
||||
Verify with `allowlist list`. This is **the** fix for "You are not invited".
|
||||
2. **Then retry the join** from a Windows/mobile client: **Add Server** →
|
||||
`crafty-mc.home.keithjackson.dev`, port **19132**. If it now connects, everything in these three
|
||||
entries is closed. If it still refuses, capture the **panel console** output during the attempt —
|
||||
that is the only place BDS's own reason is visible.
|
||||
3. **Do not set `allow-list=false`** as the fix. The game port is deliberately un-gated at the network
|
||||
layer, so the allowlist is the only thing deciding who may join. (And console `allowlist off` does not
|
||||
change `server.properties`, so it silently reverts on restart.)
|
||||
4. **Leave `transport=raknet` alone**, and keep ignoring both the `TRANSPORT TYPE ERROR` banner and the
|
||||
`too few fields` warning — the server is reachable, proven by pong and by this refusal.
|
||||
5. **`auto_start=0` / `crash_detection=0` on `K3s-Bedrock` — still outstanding.** `PATCH
|
||||
/api/v2/servers/c5837301-12b1-404e-b50e-70eafb37226b`, both true, **read them back**.
|
||||
6. **Treat `allowlist.json` and `transport=raknet` as backup-relevant PVC state.** A server recreate
|
||||
resets the allowlist to `[]` and the transport to `nethernet` — both silently.
|
||||
Reference in new issue
Block a user