Skip to content

GET /api/servers fails in container with Couldn't access platform storage: PermissionDenied #1931

Closed as duplicate

Description

@cpuodzius

Which version line?

v2 — current (@modelcontextprotocol/inspector@latest)

Which client?

All / shared core

Inspector version

2.1.0

Node version

v22.23.2

Operating system (and browser, for the web client)

No response

Transport

Not applicable / never connected

MCP server under inspection

  • Docker Image: ghcr.io/modelcontextprotocol/inspector:2.1.0
  • Runtime: Docker Swarm / Linux container
  • Deployment style: non-interactive server container behind Traefik
  • No desktop/session keyring available inside the container

Steps to reproduce

  1. POST /api/servers succeeds when adding a new server.
  2. Re-adding the same server returns: 409 {"error":"Server 'server-mcp' already exists"}
  3. UI shows no configured servers.
  4. GET /api/servers returns 500.
  5. Container logs show: Couldn't access platform storage: PermissionDenied

Expected behavior

The server list should render even when the container has no usable platform keyring. If no secret is available, the API should fall back gracefully, return the non-secret server metadata, or report per-server secret retrieval failure without making the whole catalog unreadable.

Actual behavior

When running ghcr.io/modelcontextprotocol/inspector:2.1.0 in a minimal Linux container, adding a server succeeds, but the UI remains empty. Adding the same server again returns 409, which confirms the server was persisted. The failing path is the server list endpoint: GET /api/servers returns 500 because the keyring backend cannot access platform storage.

Probable root cause

The code catches failures from keyring password reads, but the failure can happen earlier while constructing/accessing the keyring entry/provider itself. In a minimal Linux container this throws PermissionDenied, so GET /api/servers fails before it can return the catalog.

Logs, errors, or screenshots

Image

Already prototyped a fix?

The v2.1.0 image was patched so keyring initialization/read failures are caught and treated as unavailable secret storage. After that:

  • GET /api/servers returns 200
  • the previously added server appears in the UI
  • Inspector can continue operating in the containerized deployment

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is not a security vulnerability report (those go through the private advisory process).

Activity

  1. cliffhall commented on Aug 5, 2026

    @cliffhall
    Member

    Triage: Priority High (total 10)

    • Severity 4 — a core workflow is unusable: GET /api/servers 500s, so the catalog is unreadable and the UI shows no servers even though POST persisted them (the 409 on re-add confirms it). Not 5 — it is scoped to containers with no usable platform keyring, not broken on arrival for everyone.
    • Urgency 5 — actively hurting users on a published version: the affected artifact is the official ghcr.io/modelcontextprotocol/inspector:2.1.0 image.
    • Bonuses: +1 — carries the bug label. No milestone (a pass-1 triage never earns that one, by rule), no engagement yet, unassigned, not a sub-issue, and no reporter-set Fields → Priority.

    Board: #28, Status Incoming — awaiting maintainer review, so no milestone yet. Labeled v2 per the reported version line.

    Thanks for the unusually complete report — the probable-root-cause note (failure while constructing the keyring entry, not just reading a password, so the catch around the read never sees it) and the confirmation that patching it restores a 200 are exactly what makes this actionable.

    Per CONTRIBUTING.md we take fixes as issues rather than PRs, so nothing further is needed from you — but if you still have the patch you applied to the image, pasting the diff or the prompt you used here would help whoever picks this up.

  2. cliffhall commented on Aug 5, 2026

    @cliffhall
    Member

    Closing as a duplicate of #1848, which is now the single tracking issue for this bug.

    Thanks for the report — it was not wasted. Three people hit this independently in different environments, which is a large part of the evidence that it affects essentially any containerized or keyring-less deployment rather than one unusual setup:

    Root cause: @napi-rs/keyring's AsyncEntry constructor does the platform-store setup and throws when no secret service is reachable. It is constructed outside the try in get/set/delete in core/auth/node/secret-store.ts, so the graceful-degradation path that already exists never engages — the raw error escapes and 500s every GET /api/servers.

    Your confirmation that patching the 2.1.0 image to treat keyring init/read failures as unavailable storage restores a 200 is independent evidence that this diagnosis is complete.

    Subscribe to #1848 for the fix. No further action needed here.

  3. added
    containerizationRelated to the docker image or containerized operation in general
    on Aug 5, 2026
  4. cliffhall commented on Aug 6, 2026

    @cliffhall
    Member

    For the record, since this was closed as a duplicate of #1848: the fix is now open as #1945, and it is the change you root-caused here — AsyncEntry construction moved inside the try in get/set/delete, so a construction-time keychain failure follows the documented degradation contract instead of escaping as a raw error.

    After it, GET /api/servers returns 200 with the server list in a container with no D-Bus session, and only an actual attempt to save a secret hard-fails — as a KeychainUnavailableError, which the routes translate to a 503 with an actionable message rather than a generic 500.

    A related follow-up you may want to watch: #1950 covers what secret persistence should actually mean in a container, since #1945 makes the non-secret flows work but leaves the affected platforms with no way to store an OAuth client secret or a stdio env: secret at all.

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

    bugSomething isn't workingcontainerizationRelated to the docker image or containerized operation in generalduplicateThis issue or pull request already existskeyringRelated to system keychain accessv2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions