Skip to content

[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

Open

Description

@wangericnv

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

Expected 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

  1. self-assigned this
    on Sep 16, 2026
  2. deepujain commented on Sep 16, 2026

    @deepujain
    Collaborator

    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.provider values. 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 add preflight, 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.

  3. wangericnv commented on Sep 17, 2026

    @wangericnv
    CollaboratorAuthor

    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:

    mcp add alpha --url https://api.githubcopilot.com/mcp/ --env AAA_TOK --no-probe
    mcp add beta  --url https://api.githubcopilot.com/mcp/ --env BBB_TOK --no-probe

    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 add fails". 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:

    1. The rejection is correct but the message is not actionable. What the user sees is Could not confirm the policy update ... The current live policy differs from the requested document followed by Failed 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.
    2. The 64-server documentation is what led me to over-generalise. The product documents a maximum of 64 managed MCP servers per sandbox; hitting a hard failure on the second one made a per-sandbox limit of 1 look plausible. If distinct endpoints are the supported path, that doc is worth a sentence making the per-endpoint credential constraint explicit.

    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.

  4. wangericnv commented on Sep 17, 2026

    @wangericnv
    CollaboratorAuthor

    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 add evidence: every mcp add run 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-recorder and exited 0, but the preset was still absent from policy list afterwards, 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 add preflight also address the policy add --from-file path, 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.

  5. added
    NV QABugs found by the NVIDIA QA Team
    UATIssues flagged for User Acceptance Testing.
    needs: triageAwaiting maintainer classification
    on Sep 17, 2026
  6. added theissue type on Sep 23, 2026
  7. added
    area: policyNetwork policy, egress rules, presets, or sandbox policy
    area: securitySecurity controls, permissions, secrets, or hardening
    and removed
    needs: triageAwaiting maintainer classification
    on Oct 2, 2026
  8. removed their assignment
    on Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    NV QABugs found by the NVIDIA QA TeamQA Test BlockerBug that blocks nightly QA testing.UATIssues flagged for User Acceptance Testing.area: policyNetwork policy, egress rules, presets, or sandbox policyarea: securitySecurity controls, permissions, secrets, or hardening

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions