Deployment Issues
Troubleshoot Vercel deployments, production database connections, domains, and webhooks.
Build fails on Vercel
Symptom: Vercel deployment fails during the build step.
Cause: TypeScript errors, missing environment variables, or dependency issues.
Fix:
- Build locally first to catch errors before deploying:
pnpm build
-
Check Vercel build logs: Go to your project > Deployments > click the failed deployment > view build logs. The error is usually near the bottom.
-
Common build errors:
| Error | Fix |
|---|---|
Type error: ... | Fix the TypeScript error. pnpm build locally shows the same error. |
Module not found | Check import paths. The @/ alias must be configured in tsconfig.json. |
env var not found | Add the variable in Vercel > Settings > Environment Variables. |
ENOMEM (out of memory) | Add NODE_OPTIONS=--max-old-space-size=4096 as an env var in Vercel. |
- Check Node.js version: KitRocket requires Node 20+. In Vercel, go to Settings > General > Node.js Version and select 20.x.
Environment variables not available
Symptom: App deploys but crashes with "Missing environment variable" errors.
Cause: Variables not set in Vercel, or set for the wrong environment scope.
Fix:
- Go to your Vercel project > Settings > Environment Variables
- Add every variable from
.env.example - Check the environment scope — each variable can be scoped to Production, Preview, or Development
DATABASE_URL → Production, Preview (different values if separate databases)
AUTH_SECRET → Production, Preview
BETTER_AUTH_URL → Production only (set to your production domain)
-
Redeploy after adding or changing variables. Variables are injected at build time, not runtime. Click Deployments > three dots on latest > Redeploy.
-
Client-side variables must start with
NEXT_PUBLIC_:
# Available on the client (browser)
NEXT_PUBLIC_POSTHOG_KEY=phc_xxx
# Server-only (API routes, server components)
AUTH_SECRET=xxx
Database connection fails in production
Symptom: App deploys but shows "Database connection failed" or times out on page load.
Cause: Wrong connection string, IP restrictions, or connection pooling issues.
Fix:
- Use the connection pooler URL from Supabase (port 6543):
# Correct — pooler on port 6543
DATABASE_URL="postgresql://postgres.[ref]:[pass]@aws-0-[region].pooler.supabase.com:6543/postgres"
# Wrong — direct connection on port 5432 (doesn't work well with serverless)
DATABASE_URL="postgresql://postgres.[ref]:[pass]@aws-0-[region].supabase.com:5432/postgres"
-
Check password encoding: If your password contains special characters (
@,#,%), URL-encode them:@becomes%40#becomes%23
-
Check that your Supabase project is active. Free tier projects pause after 1 week of inactivity. Go to the Supabase dashboard and resume it.
-
Run migrations against production:
DATABASE_URL="your-production-url" pnpm db:push
Domain not resolving
Symptom: Custom domain shows "DNS_PROBE_FINISHED_NXDOMAIN" or "This site can't be reached."
Cause: DNS records not configured or not yet propagated.
Fix:
- In Vercel, go to Settings > Domains and add your domain
- Vercel will show the DNS records you need to add:
For apex domain (e.g., yourdomain.com):
Type: A
Name: @
Value: 76.76.21.21
For subdomain (e.g., app.yourdomain.com):
Type: CNAME
Name: app
Value: cname.vercel-dns.com
- Add these records at your domain registrar (Namecheap, Cloudflare, GoDaddy, etc.)
- Wait for propagation — usually 5-30 minutes, but can take up to 48 hours
Check propagation status:
dig yourdomain.com A
- If using Cloudflare: Set the DNS proxy to "DNS only" (gray cloud), not "Proxied" (orange cloud). Vercel handles SSL and CDN.
Webhook URL not working in production
Symptom: Payments complete but webhooks aren't received. DodoPayments shows failed deliveries.
Cause: Webhook URL still pointing to localhost or an old domain.
Fix:
- Update the webhook URL in DodoPayments dashboard to:
https://yourdomain.com/api/webhook/dodo
-
Make sure the URL uses HTTPS (not HTTP)
-
Verify the route is accessible:
curl -X POST https://yourdomain.com/api/webhook/dodo \
-H "Content-Type: application/json" \
-d '{"test": true}'
You should get a response (even a 400 error about invalid signature means the route is reachable).
- Check that the webhook secret matches between your Vercel environment variables and DodoPayments dashboard.
"Function timeout" errors
Symptom: API routes return 504 Gateway Timeout on Vercel.
Cause: Route execution exceeds the timeout limit. Vercel Hobby plan: 10 seconds. Pro plan: 60 seconds.
Fix:
- Identify the slow operation. Add timing logs:
const start = Date.now();
const result = await slowOperation();
console.log(`Operation took ${Date.now() - start}ms`);
-
Optimize database queries:
- Add indexes for frequently queried columns
- Use
select()with specific columns instead ofselect() - Avoid N+1 queries — use joins
-
Move heavy work to background jobs using Vercel Cron, Inngest, or Trigger.dev
-
Use streaming for AI routes — the connection stays open but sends data incrementally, avoiding the timeout
-
Upgrade to Vercel Pro if you need longer timeouts (60 seconds)
Static generation errors
Symptom: Build fails with "Error: Page ... couldn't be rendered statically."
Cause: A page that Next.js tries to pre-render uses dynamic data (cookies, headers, search params).
Fix:
Add dynamic rendering for pages that need runtime data:
export const dynamic = "force-dynamic";
Or if only specific parts need dynamic data, use unstable_noStore:
import { unstable_noStore as noStore } from "next/cache";
export default async function Page() {
noStore();
// ... fetch dynamic data
}
Preview deployments don't work
Symptom: Vercel preview deployments (for PRs) fail or have broken auth.
Cause: Preview URLs are dynamic, but auth callbacks and webhooks need a fixed URL.
Fix:
- For auth, set
BETTER_AUTH_URLto the preview deployment URL, or use a wildcard:
# In Vercel env vars (Preview scope):
BETTER_AUTH_URL="https://*.vercel.app"
Note: OAuth providers need each preview URL added as a callback, which isn't practical. For preview deployments, test email/password auth instead of OAuth.
-
For webhooks, preview deployments can't receive webhooks unless you configure a separate webhook URL for each preview. Most teams skip webhook testing in previews and test in staging.
-
Use a separate database for preview deployments to avoid polluting production data.
Still stuck?
- Check Vercel documentation for platform-specific issues
- Check Supabase documentation for database issues
- Ask in the Telegram community for help