Troubleshooting
A change does not show on the site #
The site caches pages, globals, reusable sections, cards and lists, and refreshes each one when it is saved through Payload. Something written past Payload's hooks (a script writing straight to the database, a restore from a backup, an import) leaves old pages in the cache.
Editors: press Clear site cache on the admin dashboard.
Scripts and deploys:
POST /api/revalidate. It drops every cached page, global, reusable section, card and list. It accepts a logged-in editor or admin, or the server's own token (the one the jobs runner uses, derived fromPAYLOAD_SECRET), which is howpnpm seed:demorefreshes a running site:curl -X POST -H "Authorization: JWT <an editor's token>" https://www.example.com/api/revalidate
Old content after a restart #
Next.js keeps its data cache on disk, in .next/cache, and a restart does not clear it, in development or with pnpm start. A database swapped under a running site (a restore, another database in .env, the demo seeded while the site was down) therefore still shows the old content.
- Call
POST /api/revalidate, or press Clear site cache, once the site is up. - Or stop the server and delete
.next/cache. In development,pnpm devsafedeletes all of.nextand starts again.
In the Docker image, .next/cache lives in the container, so a new container starts with an empty cache.
Redirect loops in a container #
If every page redirects to itself behind Docker or Kubernetes, check HOSTNAME. Docker and Kubernetes set it to the container's name, and with a named host Next.js builds its rewrites as absolute addresses, which loop. The image starts the server with HOSTNAME=0.0.0.0; keep that in your own start command or Dockerfile.
Links and SEO tags point at localhost #
NEXT_PUBLIC_SERVER_URL is not set where the site runs. Set it to the public address and restart; the image reads it when the container starts.
The health check answers 503 #
/api/health answers 503 when the database does not respond. Check DATABASE_URL and that the container can reach the database.
Scheduled posts are not published #
- Is anything running the jobs? With
JOBS_AUTORUN=falseon every container, nothing is, unless a cron calls the run endpoint withCRON_SECRET(see Background jobs). - A warning that the server could not reach itself means it ran the jobs outside a request: the publish happened, but cached pages refresh only later. Make sure the server can reach
127.0.0.1on its ownPORT. - Failed jobs stay in System → Background jobs (admins), with their error.
The server does not start because of SMTP_FROM #
The error reads "SMTP_HOST is set, so SMTP_FROM (the sender address) must be set too.": SMTP_HOST is set without a sender address. Set SMTP_FROM, or leave SMTP_HOST empty to print emails to the console.
Emails do not arrive #
Without SMTP_HOST, nothing is sent: emails go to the server's log. With it, check the server's log for the SMTP error. Form submissions are stored either way.
The AI buttons are missing #
ANTHROPIC_API_KEY is not set on the server, or the person is not allowed: ✨ Translate needs a saved document and the right to edit another language; 🖊 Proofread shows only in the default language, for editors and admins. See AI translation.
The 404 page is blank until its scripts load #
An address with no page answers 404, with <meta name="robots" content="noindex">, as it should. The page's heading and text, however, are drawn in the browser. Next.js (16.3) sends a not-found from a cached page route (the catch-all and the front page are cached, with revalidate) as an empty document, and renders the language's not-found page (src/app/(frontend)/[locale]/not-found.tsx) once the page's scripts have run.
- Visitors see the page as soon as the scripts are in, usually within a fraction of a second.
- Search engines get the
404status and thenoindextag, so nothing is indexed. - A browser without JavaScript sees a blank page.
Only fully dynamic routes render a not-found page on the server, and making the page routes dynamic would give up the page cache. To check a 404 page in a test, assert the status and the noindex tag. Read the text only after the page's scripts have loaded (tests/e2e/pages.e2e.spec.ts shows how).
The build runs out of memory #
pnpm build needs about 4 GB. Build on a bigger machine or in CI, and run the image on the small one.
next dev and CLAUDE.md #
When next dev runs under an AI coding agent, Next.js would add a block of its own to CLAUDE.md and AGENTS.md. The kit turns that off (agentRules: false in next.config.ts): CLAUDE.md holds the kit's conventions, and the development server leaves it alone. Keep the setting if you change next.config.ts.