Fix 401 Basic Auth Error on Vercel Preview Custom Domains

Short summary (what’s happening)
I have a preview deployment that should be public on [REDACTED_CUSTOM_DOMAIN], but the domain always returns HTTP 401 with WWW-Authenticate: Basic realm=“Protected”. App-level Basic Auth and middleware challenges have been disabled for preview, but the 401 persists. The response appears to come from Vercel’s edge (header server: Vercel).

Current: Visiting https://[REDACTED_CUSTOM_DOMAIN] returns HTTP/2 401 with header WWW-Authenticate: Basic realm=“Protected”. This happens for plain GET, requests with x-vercel-protection-bypass (header and query param), and requests that include a _vercel_jwt cookie set via an interactive browser flow.
Expected: After removing app-level Basic Auth for preview and assigning the domain to the staging branch, requests to the custom domain should return the app (HTTP 200) or allow the bypass header/cookie to authenticate automated clients (LHCI, curl).

import { NextResponse } from ‘next/server’
import type { NextRequest } from ‘next/server’
export function middleware(req: NextRequest) {
// Basic Auth enforcement removed for preview
return NextResponse.next()
}
export const config = { matcher: [‘/((?!_next/static|_next/image|favicon.ico).*)’] }

Preview host (internal): [REDACTED_PREVIEW_HOST] (READY)
Custom domain: [REDACTED_CUSTOM_DOMAIN] (recently removed + re-added and assigned to the staging branch)
Framework: Next.js 16 (webpack build in Vercel), rootDirectory: web/web
App-level settings: DISABLE_BASIC_AUTH=true set for Preview; app middleware modified to bypass Basic Auth in preview.
Bypass token: VERCEL_AUTOMATION_BYPASS_SECRET configured in project (value redacted)

Hey, @dkilodesigns-3444! Welcome!

Since you have VERCEL_AUTOMATION_BYPASS_SECRET configured, make sure you are using it properly:

  • Header: x-vercel-protection-bypass: <your-secret>
  • Query param: ?x-vercel-protection-bypass=<your-secret>

From an app level, double-check that:

  • DISABLE_BASIC_AUTH=true is set specifically for the Preview environment
  • The environment variable is properly deployed to your preview deployment
  • Your middleware is actually being bypassed (add some console logs to verify)

Feel free to also share the domain with us :slight_smile:

Helpful resources:

Hi Pauline

Thanks for the guidance. Per your suggestion I tested the `VERCEL_AUTOMATION_BYPASS_SECRET` flow against our preview domain `staging.floai.studio`. I have redacted secrets in the outputs below (replaced with `[REDACTED]`).

What I tested

- Plain GET to root: returns 401 from Vercel edge with `WWW-Authenticate: Basic realm=“Protected”`.

- Header bypass: sent `x-vercel-protection-bypass: [REDACTED]` — still 401.

- Query bypass: appended `?x-vercel-protection-bypass=[REDACTED]` — still 401.

- Set-bypass-cookie URL: `?x-vercel-set-bypass-cookie=true&x-vercel-protection-bypass=[REDACTED]` — still 401; curl did not observe Set-Cookie.

- `/.well-known/vercel-user-meta` — returns 204 (accessible), and responds to the bypass header.

Raw (redacted) outputs

- Plain root

```

HTTP/2 401

cache-control: public, max-age=0, must-revalidate

content-type: text/plain;charset=UTF-8

date: Sat, 10 Jan 2026 02:22:02 GMT

server: Vercel

strict-transport-security: max-age=63072000

www-authenticate: Basic realm=“Protected”

x-vercel-id: cle1::gqfj9-1768011721322-46731c330208

Authentication required

```

  • Header bypass (secret redacted)

```

HTTP/2 401

cache-control: public, max-age=0, must-revalidate

content-type: text/plain;charset=UTF-8

date: Sat, 10 Jan 2026 02:22:03 GMT

server: Vercel

strict-transport-security: max-age=63072000

www-authenticate: Basic realm=“Protected”

x-vercel-id: cle1::t4zhq-1768011723086-042bac934166

Authentication required

```

- Query bypass (secret redacted)

```

HTTP/2 401

cache-control: public, max-age=0, must-revalidate

content-type: text/plain;charset=UTF-8

date: Sat, 10 Jan 2026 02:22:04 GMT

server: Vercel

strict-transport-security: max-age=63072000

www-authenticate: Basic realm=“Protected”

x-vercel-id: cle1::pzjlq-1768011723979-613fe7ff3820

Authentication required

```

  • Set-bypass-cookie attempt (secret redacted)

```

HTTP/2 401

cache-control: public, max-age=0, must-revalidate

content-type: text/plain;charset=UTF-8

date: Sat, 10 Jan 2026 02:22:05 GMT

server: Vercel

strict-transport-security: max-age=63072000

www-authenticate: Basic realm=“Protected”

x-vercel-id: cle1::zqhbw-1768011725559-fdf2aea9441d

Authentication required

```

- `/.well-known/vercel-user-meta` (plain)

```

HTTP/2 204

cache-control: public, max-age=0, must-revalidate

date: Sat, 10 Jan 2026 02:22:25 GMT

server: Vercel

strict-transport-security: max-age=63072000

x-vercel-id: cle1::krgbx-1768011745894-2c4d5f42e1df

```

- `/.well-known/vercel-user-meta` (with bypass header)

```

HTTP/2 204

cache-control: public, max-age=0, must-revalidate

date: Sat, 10 Jan 2026 02:22:28 GMT

server: Vercel

strict-transport-security: max-age=63072000

x-vercel-id: cle1::qc6gt-1768011748799-144e2ffa76a5

```

Observations / questions

- The root path continues to return 401 from Vercel edge even when sending the bypass header/query or requesting the set-bypass-cookie URL via curl.

- The set-bypass-cookie flow did not return a Set-Cookie header to curl; this suggests the cookie-based bypass may require a browser context or interactive redirect to be issued.

- `/.well-known/vercel-user-meta` is reachable and responds to the bypass header (204), so the edge SSO metadata endpoint appears active.

Thank you — happy to run any additional tests you recommend and provide timestamps/headers as needed.