Skip to content

07. Launch Checks and Common Errors

This chapter is for the final check before you call the system live, plus the most common deployment mistakes people hit on their first pass.

Before you call the deployment done, verify the basics one more time.

Check:

  • the public site opens normally
  • the admin opens normally
  • the correct domains are being used

Check:

  • login works
  • the admin can read real project data
  • obvious configuration pages are usable

Check:

  • signup or login works
  • critical pages are not empty
  • the product can read the current app_key data correctly

If you enabled them, also check:

  • payment flow
  • AI flow
  • blog flow
  • notifications
  • check-in

2. Production debugging: Cloudflare Observability (error logs)

Section titled “2. Production debugging: Cloudflare Observability (error logs)”

When something fails in production and you cannot reproduce it locally, use the Cloudflare dashboard to inspect live Worker / Pages telemetry and errors.

Navigation (example: auth Worker):

  1. Open the Cloudflare Dashboard
  2. Go to ComputeWorkers & Pages
  3. Open the target project, e.g. zship-node1-auth (use the exact name from your wrangler config)
  4. Open Observability

From Observability you can inspect requests, error stacks, console output, and related signals—useful for 5xx responses, uncaught exceptions, and upstream failures.

If logs are empty: Observability may not be enabled for that Worker or Pages project yet. In the same project’s settings, find the Observability controls and enable them, then reproduce the issue and refresh the view.

Tip: Repeat for each service you need to debug (for example zship-node3-pay, zship-node10-ai, or your frontend Pages app)—each has its own Observability scope.

3. CDN / R2 issues: keep CDN_PUBLIC_URL aligned with the R2 public hostname

Section titled “3. CDN / R2 issues: keep CDN_PUBLIC_URL aligned with the R2 public hostname”

When uploads fail, files 404, or node6-cdn-service errors, first verify that the public base URL in the Worker matches the R2 custom domain you serve files from. If they diverge, the Worker may write objects correctly but return URLs that do not resolve to the same public entrypoint.

Two tracks below: §3.1–§3.4 are entirely in the Cloudflare Dashboard (first-time domain setup and UI walkthrough). §3.5 uses the ZShip Dev Console — for day-to-day CDN_PUBLIC_URL updates, prefer Dev Console so you skip hunting through Workers & Pages → Variables and Secrets in the CF UI.


Path A — Cloudflare Dashboard (§3.1–§3.4)

Section titled “Path A — Cloudflare Dashboard (§3.1–§3.4)”

Everything in this path happens in the Cloudflare Dashboard: R2 custom domains, Worker env vars, and optional Worker hostnames.

  1. ComputeWorkers & Pages → open zship-node6-cdn
  2. SettingsVariables and Secrets
  3. Set CDN_PUBLIC_URL to your R2 public base URL (include https://, usually no trailing path)
  1. Storage & databasesR2 object storage
  2. Under Overview, open your bucket (example name zship-cdn — use the bucket you actually created)
  3. SettingsCustom Domains
    Bind the hostname that should serve files publicly (for example https://cdn.example.com).
LocationSettingWhat to put
Worker zship-node6-cdnCDN_PUBLIC_URLSame root URL as the R2 custom domain (https://your-cdn-hostname)
R2 bucketCustom DomainsThe same hostname you configured above

They must stay in sync so zship-node6-cdn generates URLs that point at the same objects users can fetch.

3.4 Exposing the CDN Worker on the public internet

Section titled “3.4 Exposing the CDN Worker on the public internet”

If you also need the upload Worker itself on its own hostname (not only the R2 public domain), bind a domain / route to zship-node6-cdn under Workers & Pages → that Worker → SettingsDomains & Routes (or Custom Domains). Many setups only need §3.3—R2 custom domain + matching CDN_PUBLIC_URL.


Path B — ZShip Dev Console (§3.5) — preferred for routine changes

Section titled “Path B — ZShip Dev Console (§3.5) — preferred for routine changes”

Why Dev Console matters: You can edit CDN_PUBLIC_URL, push straight to the live Worker, and follow with a redeploy in one workflow — without bouncing between Cloudflare menus (Workers & Pages → … → Variables and Secrets). It matches how you already manage secrets and deploys from this repo, which cuts context switching when debugging or shipping.

3.5 Push CDN_PUBLIC_URL from Dev Console and redeploy

Section titled “3.5 Push CDN_PUBLIC_URL from Dev Console and redeploy”
  1. Open Dev ConsoleShippingDeploy (labels may match your local build)
  2. Environment variablesWorker environment
  3. Select cdn backend (maps to zship-node6-cdn)
  4. Edit CDN_PUBLIC_URL, then Push to zship-node6-cdn (or equivalent) to write vars to the live Worker
  5. Redeploy zship-node6-cdn so the change takes effect

Note: If the R2 Custom Domain has never been created, do §3.2 in the Dashboard once. After that, routine URL-only updates can stay in §3.5.

4. Common error 1: service binding target not found

Section titled “4. Common error 1: service binding target not found”
  • you renamed a Worker (does not match name in wrangler.jsonc)
  • you deployed using the wrong Cloudflare account
  • deploy order: a Worker with service bindings depends on a target that has not been deployed yet
  • keep Worker names consistent with wrangler.jsonc
  • run wrangler whoami and verify you are in the intended account
  • deploy in dependency order (Workers without bindings first)

5. Common error 2: D1, KV, or R2 resources cannot be found

Section titled “5. Common error 2: D1, KV, or R2 resources cannot be found”
  • resources were never created
  • config files still contain placeholders
  • resource IDs were copied incorrectly
  • verify the resources exist in Cloudflare
  • compare config values carefully
  • replace all placeholder values before redeploying

6. Common error 3: admin login returns 401

Section titled “6. Common error 3: admin login returns 401”
  • auth secrets are wrong
  • frontend points at the wrong auth URL
  • the domain configuration is inconsistent
  • verify auth secrets again
  • verify auth endpoints again
  • confirm the deployed frontend is using the latest environment values

7. Common error 4: pages open, but all data is empty

Section titled “7. Common error 4: pages open, but all data is empty”
  • the frontend points at the wrong backend
  • the wrong app_key is in use
  • the admin and frontend are not reading the same dataset
  • verify frontend environment variables
  • verify the real app_key
  • confirm the backend services and admin data belong to the same project

8. Common error 5: the payment page opens, but payment does not work

Section titled “8. Common error 5: the payment page opens, but payment does not work”
  • provider keys are missing
  • webhook config is incomplete
  • pricing or product data is not configured correctly
  • verify payment provider secrets
  • verify webhook configuration
  • verify product and pricing data in the admin

9. Common error 6: the AI page opens, but sending a message fails

Section titled “9. Common error 6: the AI page opens, but sending a message fails”
  • provider keys are missing
  • model config is incomplete
  • gateway or upstream settings are wrong
  • verify AI provider keys
  • verify model mapping
  • verify the deployed AI service is reading the intended environment values

10. Common error 7: Pages deploy says Invalid binding SESSION

Section titled “10. Common error 7: Pages deploy says Invalid binding SESSION”

This usually means the expected binding exists in code or config, but is not properly created or attached in the target environment.

  • verify the Cloudflare binding exists
  • verify the Pages environment is using the right binding name
  • redeploy after fixing the binding configuration
  • DNS for your sending domain is incomplete (SPF, DKIM, DMARC — follow your mail provider’s checklist)
  • Wrong SMTP / provider secrets or sender settings for node4-notify-service (admin or Worker env)
  • Broken templates or routing so requests never reach the notify Worker
  1. Follow Email for DNS and channel configuration
  2. Check Observability on zship-node4-notify (or your renamed notify Worker) for errors
  3. Send a test message from the admin and review provider delivery logs if available

12. Payment or third-party webhooks never arrive / status stuck

Section titled “12. Payment or third-party webhooks never arrive / status stuck”
  • Callback URL is not a public hostname (still on *.workers.dev or internal URL) — same as Domains & environment: node3-pay needs a real domain
  • Stripe / Creem webhook URL or signing secret does not match production (wrong environment, mixed staging/prod)
  • Provider retries expired — you may need to reconcile manually in admin
  1. Confirm the zship-node3-pay public URL matches the webhook endpoint in the payment dashboard (including https://)
  2. Use Observability on zship-node3-pay to see whether callbacks hit the Worker and whether they return 4xx/5xx
  3. Re-read Payment for price, channel, and project bindings

If the browser shows CORS errors, the frontend origin often does not match what the API allows — align SITE_URL, project domains, and gateway settings, then retry.

If something breaks, do not panic and do not rewrite half the setup at once.

Use the simplest debugging loop:

  1. identify one likely cause
  2. change one thing
  3. redeploy or retry
  4. observe the result

That is the fastest way to converge on a stable production setup.