PRACTICAL FIELD GUIDE

401 Invalid credential: why the API rejected your token

A 401 with the message Invalid credential means a token was sent but it is neither an MCPBackend API key nor an end-user session token. The value is usually a placeholder, an unset variable or a token from another system, not a permissions problem.

MCPBackend editorial team · · Examples are illustrative

The short answer

MCPBackend's data API returns 401 with the message "Invalid credential" (code unauthorized) when a request carries a token that it cannot even classify. It is not a permissions error and it is not a wrong password. The API looked at the value after Bearer, saw that it does not start with eb_ (a project API key) and does not have the three dot-separated parts of a user session token, and stopped there.

In practice the token is almost always one of these: the literal text undefined or null from an environment variable that was never set, a placeholder such as YOUR_API_KEY copied from docs, a key wrapped in quotes, or a token issued by a different system. Print the first few characters and the length of what your code really sends and the cause is usually obvious.

If a tool or proxy reports "upstream request failed: invalid credential", it is passing on the same kind of rejection from the API it called. When that API is MCPBackend, the checks below apply unchanged.

Which 401 do you have? The data API sends three different ones

  • "Invalid credential": the token is neither an eb_ key nor a JWT-shaped session token. Fix the value you send.
  • "Invalid API key": the token starts with eb_ but no active key matches it. The key was mistyped, truncated, or revoked. Create a new key and update the secret.
  • "Invalid or expired token": the token looks like a session JWT but its signature does not verify, it has expired, or it was issued for a different project. Sign the user in again against the project in the URL.
  • "Authentication required" (also 401): no token was sent at all and the table only allows signed-in users. Send the user's session token.
  • Not a 401: a valid key from another project returns 403 project_mismatch, and a key without access to the table returns 403 forbidden.

How MCPBackend reads the token

The data API takes the token from Authorization: Bearer <token> first. The scheme name is case-insensitive, but it must be followed by exactly one space and then the token. If there is no usable Bearer header, it falls back to an x-api-key header that holds the bare key.

That order has a surprising consequence. If you send Authorization: eb_123 without the word Bearer, the API finds no bearer token and no x-api-key, so it treats the request as anonymous. You then get a 401 Authentication required or a no_policy error instead of Invalid credential, which sends people looking at row policies when the real bug is the header.

// What the API sees, by header
Authorization: Bearer eb_9f2c...          -> API key (admin, per-key table permissions)
x-api-key: eb_9f2c...                     -> API key
Authorization: Bearer eyJhbGc...xxx.yyy   -> end-user session token (row policies apply)
Authorization: Bearer undefined           -> 401 Invalid credential
Authorization: Bearer "eb_9f2c..."        -> 401 Invalid credential (quotes are part of the value)
Authorization: eb_9f2c...                 -> no token: treated as anonymous

Fix it in four checks

  • Log a fingerprint, not the secret: the first four characters and the length. eb_ followed by a long random string is a server key; three segments separated by dots is a session token; anything else will get Invalid credential.
  • Check the environment the code runs in. A key set in your shell or a local .env file is not automatically present in your host's build or runtime settings. After adding it, redeploy, because many hosts read variables only at build time.
  • Strip wrapping quotes and whitespace. Values pasted into a dashboard with quotes keep them, and a trailing newline from a secrets file can break the header.
  • Use the right credential for the caller. Server code uses an eb_ key with only the table permissions it needs. Browser code uses the token returned by /auth/login or /auth/signup for the signed-in user, never a server key.
const key = process.env.MCPBACKEND_KEY?.trim().replace(/^"|"$/g, "");
if (!key?.startsWith("eb_")) throw new Error("MCPBACKEND_KEY is missing or not an eb_ key");
console.log("using key", key.slice(0, 4) + "...", "length", key.length); // never log the full key

const res = await fetch(`https://data.mcpbackend.com/v1/${projectId}/db/tasks?limit=1`, {
  headers: { authorization: `Bearer ${key}` },
});
if (res.status === 401) console.error((await res.json()).error.message); // which 401 is it?

API keys, session tokens and MCP OAuth are different credentials

Three kinds of credential exist around an MCPBackend project and only two work on the data API. Project API keys (eb_...) are created in the dashboard or with the create_api_key MCP tool and belong in server code. Session tokens come from the project's own signup and login endpoints and identify one of your app's users. The OAuth grant your MCP client holds lets your coding agent manage the project through MCP; it is not a data API credential, so do not copy it into your app.

A token issued by another service, such as a Supabase, Auth0 or Clerk JWT, has the three-part shape of a session token, so it fails with Invalid or expired token rather than Invalid credential. Either way the fix is the same: send a credential this project issued.

Put it into practice

  1. Log the first four characters and the length of the token your server actually sends, never the whole value.
  2. Confirm it starts with eb_ for a server key or has three dot-separated parts for a user session token.
  3. Check the header is exactly Authorization: Bearer followed by one space and the token, or x-api-key with the bare key.
  4. Retry one read against the same project and compare the error message before changing any permissions.

What this looks like

ILLUSTRATIVE EXAMPLE

A deploy reads MCPBACKEND_KEY from the wrong environment, so the app sends Authorization: Bearer undefined. The API answers 401 Invalid credential until the variable is set and the app redeployed.

A boundary to keep clear

Do not paste a server API key into browser code to make the error go away. Server keys bypass row policies; signed-in users should send their own session token.

MCPBackend context

Use get_project_api or the dashboard's generated OpenAPI contract for your project's exact data-plane routes. Machine keys and end-user tokens have different access models. Treat error status and JSON code together, keep credentials out of URLs, and test against disposable records before changing real data.

Take the next step

Inspect the current project contract, try the change with disposable data, and verify the result through the same credentials your app will use. Record the expected response and one denied-access case before release.

Frequently asked questions

What does "Invalid credential" mean on a 401?

The API received a token but could not recognize it as any credential type it accepts. On MCPBackend that means the value is neither an eb_ API key nor a three-part session token, which usually points to an unset variable, a placeholder or a quoted value.

What does "upstream request failed: invalid credential" mean?

A tool, proxy or SDK called another API and that API rejected the credential it was given. Fix the token that the tool sends upstream: check which variable it reads, that it is set where the tool runs, and that it is the right type of key for that API.

Is a 401 Invalid credential the same as invalid_credentials on login?

No. invalid_credentials comes from POST /auth/login when the email and password do not match. Invalid credential (code unauthorized) comes from any data request whose bearer token is unusable.

My key worked yesterday. Why do I get Invalid API key now?

The key was probably revoked or replaced, or the deployed value was truncated. Revoked keys stop working within seconds. Create a new key, store it as a secret, redeploy and test one read.

Sources and further reading

These references explain the underlying protocols and design principles. For supported MCPBackend operations and exact request shapes, inspect your project’s generated API contract.