Repository navigation
[All Platforms][Policy&Network] only one managed MCP server can be registered per sandbox; every later mcp add fails to activate its generated policy #11895
Description
Note
Re-verified reopening of #11798 — closed via #11863 ("fix(policy): allow full
activation wait"), whose merge commit is confirmed an ancestor of v0.0.126
(compare against the tag reports behind_by: 0). Re-verification on v0.0.126
today still reproduces the original symptom, unchanged and deterministically. The
evidence from that run is below.
Description
A sandbox can hold only one managed MCP server. The first nemoclaw {sandbox} mcp add
succeeds, but a subsequent add of a differently-named server with a distinct credential
key fails while activating its generated policy, and the server is not registered. The
failure is deterministic and repeats on retry.
This makes the documented multi-server workflow unusable: mcp add advertises no
per-sandbox limit of one, and the product separately documents a maximum of 64 managed
MCP servers per sandbox, which cannot be approached because the second registration
already fails.
Platform scope: re-verified on DGX Spark (Ubuntu 24.04, aarch64). The original report
also covered Ubuntu 22.04 x86_64, so it is not platform-specific.
Regression: the fix for this issue shipped and is present in the tested build, but the
behaviour is unchanged.
OpenShell issue: No — the failing command is NemoClaw's own mcp add. The gateway
stays up and answers, and the first server's policy activates normally through the same
path.
Environment
Device: NVIDIA DGX Spark
OS: Ubuntu 24.04.4 LTS
Architecture: aarch64
OpenShell CLI: openshell 0.0.116
NemoClaw: nemoclaw v0.0.126
Steps to Reproduce
# 1. Onboard a fresh OpenClaw sandbox and confirm it reaches Ready.
nemoclaw onboard --fresh --name {sandbox} --non-interactive --yes
# 2. Export two distinct host credential variables.
export AAA_TOK=... BBB_TOK=...
# 3. Register the first server.
nemoclaw {sandbox} mcp add alpha --url {mcp url} --env AAA_TOK --no-probe
# 4. Register a second server, different name and different credential key.
nemoclaw {sandbox} mcp add beta --url {mcp url} --env BBB_TOK --no-probe
# 5. List the registered servers.
nemoclaw {sandbox} mcp list
# 6. Repeat step 4 after a short wait, to show the failure is not transient.
nemoclaw {sandbox} mcp add beta --url {mcp url} --env BBB_TOK --no-probeExpected Result
Both servers register. mcp list shows alpha and beta, each with its own policy,
provider and credential key.
Actual Result
onboard exit 0, phase Ready
mcp add alpha exit 0
Applied preset: mcp-bridge-alpha
MCP server 'alpha' added to sandbox '{sandbox}'.
mcp add beta exit 1
Could not confirm the policy update for sandbox '{sandbox}':
OpenShell did not confirm the policy submission. The current live
policy differs from the requested document; the update remains
unconfirmed.
Failed to activate generated MCP policy 'mcp-bridge-beta'.
mcp list exit 0, shows only:
alpha policy provider env: AAA_TOK
mcp add beta (retry) exit 1, byte-identical output
The second server never appears in mcp list, and the retry after a wait produces the
same two messages, so the failure is deterministic rather than a timing artifact — which
is the part the "allow full activation wait" change would have been expected to address.
Activity
deepujain commentedon Sep 16, 2026
I traced the deterministic failure past the earlier timeout change. The reproduction registers two different credential providers for the exact same URL. That produces two network entries with identical host, port, and path selectors but different
credential_binding.providervalues. OpenShell correctly rejects that policy because it cannot safely choose which credential applies to an indistinguishable request.I have a focused candidate that rejects this case during
mcp addpreflight, before creating a provider or mutating policy, with a clear explanation to use one managed definition for that URL or a distinct endpoint. It keeps separately credentialed servers at distinct endpoints supported and replaces the live OpenClaw E2E case with this exact regression.Supporting two aliases with different credentials for the same exact endpoint would require a different credential aggregation or multi-binding design; accepting the current composed policy would weaken the credential boundary.
wangericnv commentedon Sep 17, 2026
You are right, and my report overstated its scope. Thank you for tracing it properly.
I re-read the evidence I actually published, in this issue and in #11798, and in both the two servers were registered against the same URL:
So every run behind both reports is the exact shape you identified: one endpoint, two credential providers, two network entries whose host/port/path selectors are indistinguishable. I never tested two managed servers at distinct URLs, yet the title and description generalised to "only one managed MCP server can be registered per sandbox" and "every later
mcp addfails". That generalisation is not supported by the evidence I provided, and I should not have made it.Two things I think still stand, for whatever they are worth:
Could not confirm the policy update ... The current live policy differs from the requested documentfollowed byFailed to activate generated MCP policy. Nothing points at a credential-binding conflict or at the duplicate endpoint, so the natural reading is "policy activation is broken", which is how I read it. Your preflight rejection with an explicit explanation addresses exactly this, and it is the right fix.What I have not verified, and cannot currently verify for lack of a free host: whether two managed MCP servers at distinct URLs register cleanly. If they do, my headline claim is simply wrong and the title should narrow to the same-endpoint case. I would rather say that plainly than leave you designing against an inflated scope. I am happy to run that check and report back once a host frees up; if you already know the answer, that settles it faster than I can.
I have posted the same correction on the internal tracking item, which was flagged as a test blocker on the basis of the broader claim, so that flag gets re-assessed too.
wangericnv commentedon Sep 17, 2026
Following my own correction above — I under-reported, and I want to flag it before the preflight fix is scoped, because there is a second repro that your diagnosis does not cover.
My correction is accurate about the
mcp addevidence: everymcp addrun in both reports used one endpoint with two credential keys, so the duplicate-selector rejection is the right explanation for that shape.But the predecessor issue #11798 also carries a different repro that I did not restate above, and which does not exist in this issue's thread at all — so it may not have reached you. It involves no duplicate endpoint and no competing credential bindings:
nemoclaw {sandbox} policy add --from-file {preset}.yaml --trusted-private-host 203.0.113.10 --yes # exit 1 # Could not confirm the policy update for sandbox '{sandbox}': OpenShell did not confirm # the policy submission. The current live policy differs from the requested document; # the update remains unconfirmed.That is a single custom network preset applied from a file on a freshly onboarded sandbox. Repeating the identical command fails identically, and the preset never appears in
policy list. Reproduced on two aarch64 hosts on v0.0.124.Recorded alongside it, and worth checking while you are in this code: on another sandbox the first custom preset add printed
Applied preset: qa-recorderand exited 0, but the preset was still absent frompolicy listafterwards, and every later add on that sandbox then failed with the same "could not confirm" message. If that holds, a policy submission can report success without being applied, which would make the "one server only" appearance a downstream symptom rather than the cause.So the open question for your candidate fix: does rejecting duplicate-endpoint registrations at
mcp addpreflight also address thepolicy add --from-filepath, or is that a separate defect that would survive the fix? If it is separate, narrowing this issue to the MCP case is still right, but the policy-preset failure should not be closed with it.I would rather over-communicate this than have you scope against an incomplete picture — my correction above swung too far the other way.
fix(mcp): reject ambiguous credential aliases (#11917)