Vercel Deployed to Production When You Asked for Preview (2026)

If you ran vercel deploy --target=preview and got a Production deployment, the flag was not ignored at random. It was the project's first deployment, and that rule outranks the flag.

Vercel's docs are explicit about the rule itself. What they do not say, and this is the actual gap, is that it overrides --target=preview. The list of things it happens "even when you" do covers importing a repo, running vercel without --prod, and deploying from a non-production branch. An explicit preview target is not on that list, so people reasonably assume passing one is different. It is not.

TL;DR

The first deployment of a new Vercel project is always Production, and --target=preview does not change that. The deployment then builds with Production-scoped environment variables, because classification is what selects the env scope. Whether it ends up publicly reachable depends on your plan and domains, not on what you intended. On a brand-new project, run vercel --prod --skip-domain first to get the mandatory production deployment out of the way.

What the docs actually say

From Vercel's Environments documentation, under "First deployment":

The first deployment of a new project is always a production deployment. This happens even when you: Import a Git repository in the dashboard / Run vercel or vercel deploy from the CLI without --prod / Deploy from a branch that is not your production branch

The CLI reference repeats it under --prod: "The first deployment of a new project is always a production deployment, even when you omit --prod."

Both pages describe the same rule in terms of what you omit. Neither addresses what happens when you explicitly ask for something else. That is the whole confusion, and it is why a run of reports landed in Vercel's community forum between 2026-07-13 and 2026-08-08, along with vercel/vercel#17069, which is still open.

Both doc pages carry last_updated stamps from late July 2026, after the reports started. Vercel has not said whether the two are connected, so treat that as a coincidence you can see rather than a cause you can prove.

It is a first-deployment thing, and that matters

The forum thread titles say the CLI "ignores" the flag, which sounds like it could hit you any time. The evidence does not support that.

A Vercel staff member tried to reproduce it on later deployments on 2026-07-23 and reported that --target=preview was respected every time, with non-production branches going to preview as expected. The next day the reporter in that thread worked out why his retries kept failing:

After each unexpected Production deployment, I deleted that exact deployment and confirmed the project returned to zero deployments. Therefore, every retry may have remained the project's "first deployment."

So the honest version is narrower than the headline: on a project with zero deployments, --target=preview will not save you. After that first one exists, the normal rules apply. If you think you are seeing this on an established project, check your deployment list before assuming it is the same bug.

The part that actually matters for security

Classification is not just a label in the dashboard. It selects which environment variables the build receives.

Vercel's environment variable docs put it plainly: a variable scoped to Production "will be applied to your next Production Deployment." A deployment classified Production is that deployment. One reporter's test build confirmed how far it propagates, coming back with VERCEL_ENV, VERCEL_TARGET_ENV and OIDC_ENVIRONMENT all reading production on a deployment created with --target preview.

That last one is worth pausing on. If you use OIDC federation to let your app assume a cloud role without long-lived keys, the environment name is part of what the trust policy matches. A build you thought was a preview can present itself as production to your cloud provider.

Two builds, same commit, different blast radius. The one classified Preview reaches your preview database. The one classified Production reaches whatever your production variables point at, and the only difference is a classification you did not choose.

Whether it is publicly reachable is a separate question

This is where a lot of the alarm in those threads outruns what anyone established, so here is the careful version.

Standard Protection "protects all deployments except production domains," and on Hobby it is the only option available. Vercel's own note is blunt: "This protects your preview deployments and deployment URLs, but your production domain remains publicly accessible. To protect production domains, you need a Pro or Enterprise plan."

Read alone, that sounds like every misclassified deployment lands on the open internet. Two things cut against it.

First, in July 2025 Vercel changed Standard Protection for new projects to also cover automatically generated domains, including the production branch domain like project-git-main.vercel.app. Existing projects can opt into that behavior from project settings. So a brand-new Hobby project with no custom domain attached is usually gated, and the genuinely exposed cases are narrower: a project with a custom production domain, or an older project that never took the update.

Second, the reports themselves disagree about whether a production alias got assigned at all. Some users say it did and served publicly. At least one says no alias was created. None of it was confirmed by Vercel staff.

And the detail nobody in those threads had: every reporter who mentioned it said their Production environment variables were empty. They had scoped everything to Preview. So the scenario where a misclassified deployment serves real production secrets to the public is mechanically possible and, as of today, not something anyone has actually documented happening. Several of the test builds simply failed, because the production scope had nothing in it.

That is the accurate shape of the risk. It is worth fixing. It is not worth panicking about.

The check to run right now

Five minutes, three commands.

1

List your deployments and look at the target column. Anything marked Production that you did not intend to promote is the thing to investigate.

vercel ls
2

Ask what your production domain is currently serving, and confirm it is the deployment you think it is.

vercel inspect <your-production-domain>
3

Open your project's Deployment Protection settings and check two things: which scope is selected, and whether the project predates July 2025. If it does and it is still on the old Standard Protection behavior, the settings page offers the update.

If step 1 turns up a Production deployment you did not want, delete it after you have a real production deployment in place, and rotate anything your production variables point at if the deployment was publicly reachable for any length of time. Rotating is cheap. Establishing exactly who hit a URL is not.

Doing it right on a new project

The workaround comes from Vercel staff in the same thread, and it works because it stops fighting the rule.

Get the mandatory production deployment out of the way
# Creates the required first production deployment
# without promoting any domain to it
vercel --prod --skip-domain

# Later, when you actually want it live:
vercel promote <deployment-url>

--skip-domain is documented: it "will disable the automatic promotion (aliasing) of the relevant domains to a new production deployment," and it must be used with --prod.

One caveat to carry with it. That deployment is still recorded with a Production target, so it builds with production environment variables even though no domain points at it. If your production scope holds live credentials, the build has them. On a brand-new project it usually does not, which is exactly why doing this on day one is easier than doing it later.

After that first deployment exists, vercel and vercel --target=preview behave the way the docs describe.

Why did Vercel deploy to production when I used --target=preview?

Almost certainly because it was the project's first deployment. Vercel's docs state that the first deployment of a new project is always a production deployment, and that rule wins over the flag. What the docs do not currently say is that it overrides an explicit --target=preview, which is why this keeps catching people out.

Does this keep happening after the first deployment?

There is no confirmed case of it. A Vercel staff member tried to reproduce it on later deployments in July 2026 and could not, and the reporter in that thread realised he had been deleting each test deployment, which returned the project to zero deployments and made every retry a first deployment again. Treat it as first-deploy behavior until someone shows otherwise.

Does a misclassified deployment get my production environment variables?

Yes. Variables scoped to Production apply to the next Production deployment, and classification is what decides which deployment that is. One user's test build reported VERCEL_ENV, VERCEL_TARGET_ENV and OIDC_ENVIRONMENT all set to production on a deployment created with --target preview.

Is that deployment publicly accessible?

It depends on your plan, your domains, and when the project was created. Standard Protection covers everything except production domains, and on Hobby it is the only option. Since July 2025 new projects on Standard Protection also cover auto-generated production domains, so a brand-new Hobby project with no custom domain is usually gated. A custom production domain, or an older project that never opted into that change, is not.

How do I create a preview deployment on a brand-new project?

Get the mandatory production deployment out of the way first. vercel --prod --skip-domain creates it without promoting any domain to it, and vercel promote finishes the job later when you want it live. It is still recorded as a Production-target deployment, so it builds with production environment variables.

Find Out What Your Production URL Is Serving

Our scanner checks your live deployment for secrets baked into the client bundle, unprotected endpoints, and the config that follows an environment variable into production.

How-To Guides

Vercel Deployed to Production When You Asked for Preview (2026)