Skip to content

GitHubProvider: a transient GitHub 5xx invalidates every active session #4854

Description

@benjohngf

What happened?

GitHubTokenVerifier.verify_token() returns None for any non-200 response from
https://api.github.com/user, so a GitHub 5xx produces the same result as an
invalid token. Clients receive invalid_token/401, discard the session, and
re-run the OAuth flow — which also calls GitHub, and also fails.

During the GitHub incident on 2026-08-17 ("Partial System Outage"), four
self-hosted servers using GitHubProvider were unusable for roughly five hours,
reconnect-looping. Tokens that had verified successfully seconds earlier were
rejected.

Expected: a transient upstream failure would be distinguishable from a rejected
credential, and would not invalidate sessions that verified moments before.

Related: #3619 (structured auth failure reasons), #4850 (same 401 symptom,
different cause — that report's token is valid offline; here the rejection
follows an upstream 503).

Example Code

"""A 503 from GitHub is indistinguishable from a 401: both yield None."""
import asyncio
import httpx
from fastmcp.server.auth.providers.github import GitHubTokenVerifier


def client_returning(status: int) -> httpx.AsyncClient:
    async def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(status, json={"message": "simulated"})
    return httpx.AsyncClient(transport=httpx.MockTransport(handler))


async def main():
    for status in (401, 503):
        verifier = GitHubTokenVerifier(http_client=client_returning(status))
        result = await verifier.verify_token("any-token")
        print(f"GitHub {status} -> verify_token returned {result!r}")

asyncio.run(main())

# GitHub 401 -> verify_token returned None
# GitHub 503 -> verify_token returned None

Version Information

FastMCP version:                                        3.4.6
MCP version:                                           1.29.0
Python version:                                       3.12.14
Platform:          Linux-6.18.38-Unraid-x86_64-with-glibc2.41
FastMCP root path:    /usr/local/lib/python3.12/site-packages

Also reproduced identically on 3.4.7 (same MRE, same output).

Metadata

Metadata

Assignees

Labels

authRelated to authentication (Bearer, JWT, OAuth, WorkOS) for client or server.bugSomething isn't working. Reports of errors, unexpected behavior, or broken functionality.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions