All guidesMore providers: databases, auth, hosting, email and payments
On this page

Vercel BotID message

Vercel

Possible misconfiguration of Vercel BotId. Ensure that the client-side protection is properly configured

By Ohad Krispin, founder of VibeRaven · LinkedIn

"Possible misconfiguration of Vercel BotId. Ensure that the client-side protection is properly configured" is logged by checkBotId() from the botid package when the request it checks does not carry the headers the BotID client adds. That happens when the route and method are missing from the client protect list, when the client setup does not load, or when the request is not a fetch from a page, such as curl or a plain HTML form with action and method. Add the path and method the message prints to initBotId({ protect: [...] }) in instrumentation-client.ts, send the request with fetch or a server action, and test on a deployed Preview, because locally checkBotId() always returns isBot: false. Reproduced with botid 1.5.12 on 2026-10-31.

What does the full message look like, in a preview and in production?

In botid 1.5.12, checkBotId() looks for an x-is-human header on the request. When it is missing, it logs the long message unless VERCEL_ENV is production, where it logs a shorter one, and then carries on asking Vercel for a verdict. We ran it in a plain Node script on 2026-10-31 with NODE_ENV=production and no request context, so the method and path show as a placeholder; in your function logs they show the real values. Our script then stopped on a missing OIDC token header, which does not happen inside a deployed function.

Possible misconfiguration of Vercel BotId.
Ensure that the client-side protection is properly configured for 'POST /api/signup'.
Add the following item to your BotId client side protection:
{
  path: '/api/signup',
  method: 'POST',
}
More info at https://vercel.com/docs/botid/get-started#add-client-side-protection

// with VERCEL_ENV=production:
Possible misconfiguration of Vercel BotId or malicious request to 'POST /api/signup'. More info at https://vercel.com/docs/botid/get-started#add-client-side-protection

Does a server action or an HTML form need a different setup?

The Vercel guide says the protect list holds paths your app routes to: API endpoints, dynamic routes with wildcards, and server actions invoked from a page, where you list that page. Not adding the protected route to the client list makes checkBotId() fail. The form submissions guide says BotID does not support traditional HTML forms that use the action and method attributes, because the browser handles them natively. Submit with fetch, or use a server action inside the form, as that guide shows.

Why does checkBotId() return isBot false on localhost?

Vercel documents that in development checkBotId() always returns { isBot: false }. To test your blocked branch locally, pass developmentOptions.bypass, which Vercel says is ignored in production. We ran both calls with botid 1.5.12 and NODE_ENV=development on 2026-10-31.

[Dev Only] Without setting the developmentOptions.bypass value, the bot protection will return HUMAN.
default: {"isHuman":true,"isBot":false,"isVerifiedBot":false,"bypassed":true}
BAD-BOT: {"isHuman":false,"isBot":true,"isVerifiedBot":false,"bypassed":false}

Checklist

How to fix it, then check the fix

  1. 01
    Add the exact method and path from the log line to the client protect list. On Next.js 15.3 and later this goes in instrumentation-client.ts:
    import { initBotId } from "botid/client/core";
    
    initBotId({
      protect: [
        { path: "/api/signup", method: "POST" },
      ],
    });
  2. 02On Next.js before 15.3, mount the BotIdClient component with the same protect list in the head of app/layout.tsx. The current Vercel guide says the withBotId wrapper in next.config is no longer needed.
  3. 03Send the request from a page with fetch, or call a server action from a form. curl and native HTML forms do not carry the BotID headers, and Vercel says a direct visit or curl to a protected route is blocked in production.
  4. 04
    Keep the client and server packages on one version, as the Vercel testing guide says:
    npm ls botid
  5. 05Deploy to a Preview first, submit the form from the page, and read the function logs: the message is gone and checkBotId() returns a real verdict.
  6. 06To test the blocked branch locally, call checkBotId({ developmentOptions: { bypass: "BAD-BOT" } }) and check that your route answers 403.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Does Vercel BotID cost money?

Vercel lists Basic as free on all plans. Deep Analysis is $1 per 1000 checkBotId() Deep Analysis calls on Pro and custom on Enterprise, and you turn it on under Firewall, Rules in the project.

Does BotID cover a sign-up that the browser sends straight to Supabase?

Not by itself. The protect list names paths that your app routes to, so a request the browser sends directly to Supabase never reaches checkBotId(). Send the sign-up through a route handler or server action and call checkBotId() there.

Why does curl get blocked in production?

BotID runs JavaScript in the page session and sends headers to the server. Vercel says that testing with curl or visiting a protected route directly will block you in production, so test with a fetch from a page in your app.