abhigyanpatwari/GitNexus · error
-32001
-32001
Error message
Unauthorized
What it means
The MCP HTTP transport supports optional Bearer auth: when McpHttpOptions.authToken is configured, every request must carry 'Authorization: Bearer <token>' exactly. The comparison is constant-time (timingSafeEqual with a length-matched dummy), and a missing, malformed, or wrong token gets a JSON-RPC-formatted 401 with code -32001. When no authToken is set, all requests pass through.
Source
Thrown at gitnexus/src/mcp/http-transport.ts:109
// we create a same-length dummy so the comparison always runs in full.
let valid = false;
if (typeof header === 'string') {
const a = Buffer.from(header);
const b = Buffer.from(expected);
if (a.length === b.length) {
valid = timingSafeEqual(a, b);
} else {
// Different lengths — run dummy comparison to preserve constant time.
timingSafeEqual(Buffer.alloc(b.length), b);
}
}
if (valid) {
next();
return;
}
res.status(401).json({
jsonrpc: '2.0',
error: { code: -32001, message: 'Unauthorized' },
id: null,
});
};
}
/**
* Returns true when an Origin should be allowed by the no-auth (loopback-only)
* CORS policy — i.e. it is absent (non-browser caller) or a loopback origin.
*
* WHATWG URL keeps the brackets on IPv6 literals
* (`new URL('http://[::1]/').hostname === '[::1]'`) and canonicalizes the
* IPv4-mapped loopback to `[::ffff:7f00:1]`; loopback IPv4 is the whole
* 127.0.0.0/8 block — so all of those forms are matched explicitly.
*/
export function isLoopbackOrigin(origin: string | undefined): boolean {
if (!origin) return true; // no Origin → non-browser caller; CORS is not the control thereView on GitHub (pinned to aac7515d2a)
Solutions
- Send the identical token: header 'Authorization: Bearer <authToken>'
- Re-copy the token from the server configuration and watch for trailing newlines or quotes in .env values
- If a proxy fronts the server, configure it to forward the Authorization header
- For trusted local use, run the server without authToken (loopback-only no-auth mode)
Example fix
# before
client = MCPClient('http://127.0.0.1:4747/mcp') # no header → 401 -32001
# after
client = MCPClient('http://127.0.0.1:4747/mcp',
headers={'Authorization': f'Bearer {TOKEN}'}) Defensive patterns
Strategy: validation
Validate before calling
const headers = authToken
? { Authorization: `Bearer ${authToken.trim()}` }
: {};
await fetch('http://127.0.0.1:4747/mcp', {
method: 'POST',
headers,
body: JSON.stringify(initializeRequest),
}); Try / catch
// on a JSON-RPC 401 with code -32001: refresh the token from config and retry once
if (res.status === 401 && body?.error?.code === -32001) {
token = loadTokenFresh();
return request(path, payload, /* attempt */ 2);
} Prevention
- Load the bearer token from the same config the server uses; trim whitespace/newlines
- Verify proxies forward the Authorization header
- For loopback-only local use, run the server without authToken instead of weakening the client
When it happens
Trigger: Connecting an MCP client to the gitnexus streamable-HTTP endpoint with the Authorization header unset, mistyped, or with a scheme/prefix mistake ('token' instead of 'Bearer token'), while the server runs with an authToken configured.
Common situations: Token rotated on the server but the client config kept the old value; a reverse proxy stripping the Authorization header; trailing newline/quote pollution from .env files; browser-based clients that cannot set the header on the first request.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ${name} must be a positive integer, got "${raw}"
- ${name} must be a positive integer <= ${max}, got "${raw}"
- GITNEXUS_EMBEDDING_REQUEST_DIMS must be a positive integer,
- Embedding endpoint returned an unparseable response (${safeU
- Embedding endpoint returned an unexpected response shape (${
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/3e73d1b87ca63e4a.
Report an issue: GitHub.