Skip to content
Siteon
Contents Common errors and fixes

Docs

Common errors and fixes

Look up the cause and fix from a symptom or error code (402, 409, 451, and more). Covers issues hit both by the people building the site and by the owners using the dashboard.

Siteon is infrastructure for AI-built websites: it adds hosting, a CMS your client can edit, contact forms, analytics and control from AI agents (CLI and MCP) around static HTML built with AI or by hand, so it is ready to ship.

Values don't appear (the HTML text stays as is)

  1. Wait a moment. With Siteon hosting, changes appear within 15 seconds. With the relay and data-embed, the public JSON is cached for 60 seconds, so it can take up to 1 minute
  2. Check the relay's environment variables. If either CMS_SITE or CMS_ORIGIN is missing, the relay does nothing
  3. Check with a GET request. If curl -sD - -o /dev/null https://example.com/ | grep -i sitekit prints x-sitekit-rendered: 1, the relay is working. curl -I (HEAD) does not get this header, so don't take its absence as a sign the relay isn't working
  4. Check the key spelling. data-cms="hours.days" is the combination of groups[].key and fields[].key in schema.json
  5. If a list is empty, check the publish status. Draft articles are not listed

Part of the page breaks, or there are extra closing tags

A marked element contains an element with the same tag name. <div data-cms="x"><div>…</div></div> breaks. Use a different tag inside, such as <span>.

Attributes aren't set

  • Did you put two data-cms-attr entries on one element (href:url data-color:color)? With two, neither is set. Split them across elements
  • Uppercase tag names or attribute names are ignored
  • Attributes that take a URL won't accept values starting with javascript: and similar schemes

The news section stays empty (not even the "nothing yet" message)

If data-cms-filter leaves zero items, neither rows nor data-cms-empty are shown. data-cms-empty only checks whether the list itself is empty. On tag pages, the relay uses the already-filtered list (Editable areas).

The article page's <title> or OGP shows site-wide values, or <title> appears twice

Put a <template data-cms-entry="news"> in <head> as well, and write <title> and <meta> inside it. Add data-cms-fallback="news" to the static <title> (A page per article).

Text colors or tag colors don't apply

Your site's CSS doesn't define the six colors such as .sk-c-red, or .sk-tag[data-color=…]. The attributes are output, but there are no rules for them. Define all six colors from the start.

Values are inserted twice, or list values look wrong

On a site that uses the relay, the script also has data-embed. Embedding can't run twice. Remove data-embed.

"Please check your input" appears (invalid_request)

  • A required field is empty
  • A value breaks a type constraint (text is limited to 200 characters, email is not in email format, and so on)
  • Check that each input's name matches fields[].key in schema.json. Fields with errors get aria-invalid="true"

Submitting returns not_found

The value of data-sitekit-form="…" doesn't match forms[].key in schema.json, or the site ID in data-site is wrong.

Clicking submit shows "Could not send"

  • If the browser's developer tools show a CORS error, or the response is 403 origin_not_allowed, that page's origin isn't in the site's allowed origins (www or not, scheme and port must match exactly). This submission was not saved. See the next section
  • rate_limited means more than 20 submissions in 10 minutes from the same source. Wait a while and it will go through

Forms return 403 (origin_not_allowed)

The domain of the page with the form is not in the site's allowed origins. The submission is not saved and does not count toward your quota.

  • In the dashboard, add the page's domain exactly as location.origin prints it in the console to "Settings" → "Domains and site name" → "Domains that may submit forms". https://www.example.com and https://example.com are different
  • A Free site can only register development domains (*.pages.dev and similar). To add your own domain, move the site to a paid plan (402 upgrade_required)
  • A custom domain on Siteon hosting is added automatically once it is "Active"

Full steps are in Fixing 403 origin_not_allowed.

Only one checkbox value arrives

When several inputs share the same name, only the last value is sent. Use separate keys (topic_a, topic_b).

A submission was sent but never arrived

  • Is the honeypot (_hp) filled in? Submissions with it filled in look successful on screen but are not saved. Add autocomplete="off" and tabindex="-1", and place it off-screen
  • If the submission is in the dashboard's inquiry list, it was saved. What didn't arrive is the notification (see the next section)

Notifications don't arrive

Open the inquiry's details to see whether each notification succeeded. A ✗ means "the notification didn't get through", not "the inquiry is gone". Failed notifications can be resent.

  • Nothing is recorded — That notification isn't configured. In the dashboard, go to "Settings → Notifications → each form", enter a destination, and turn it on
  • Slack — If the channel was deleted or the app was removed, issue a new Webhook URL and enter it again
  • The thank-you email isn't sent — It is sent only when the form has a type: "email" field and it has a value
  • You edited schema.json but the destination didn't change — Destinations aren't set in schema.json. The dashboard settings are the source of truth

GTM doesn't count form submissions

  • Did you change the completion event name in the dashboard but leave the GTM trigger on the old name?
  • On a site that uses the relay, setting both data-gtm and a GTM ID in the dashboard loads conflicting containers. Remove data-gtm
  • Submit the form for real in GTM preview mode and check that the completion event appears in the event list

Webhooks don't arrive or fail

Check the latest delivery results in the dashboard under "Settings → Advanced → Webhooks" (or siteon webhooks list).

  • You can't add one — Is the site on a paid plan (not available on Free)? Is the URL https://, without an explicit port, an IP address, or an internal name like localhost or .local (destination rules)?
  • It redirects — 3xx isn't followed and counts as a failure. Register the final URL instead
  • It times out — Return 2xx within 10 seconds. Queue heavy work and answer first
  • The signature doesn't match — Compute it over the body before parsing it as JSON, and use the whole secret including whsec_ (verifying the signature)
  • The same inquiry arrives twice — That's a retry. Use Idempotency-Key to skip IDs you've already processed

Preview pages show up in search results

List only your production hosts in the relay's CMS_INDEXABLE_HOSTS (Hosting and delivery).

Deploys stop

The CLI stops before uploading anything when the problem can be detected in advance. With --json, the code is in error.

CodeCauseFix
dev_publish_paused (503)Publishing on Free sites is temporarily paused by the operator (for example, against abuse)Try again later. If it is urgent, move that site to a paid plan
billing_inactive (402)Payment is 8 or more days overdueCheck the payment method under billing in the dashboard. Things resume once payment is confirmed
deploy_too_large / too_many_files (402)Exceeds the plan's storage or file countRemove unneeded files (source maps, original images, and so on), or upgrade the plan
file_too_large (413)A single file exceeds 25 MiBHost videos elsewhere and embed them. Shrink images
file_type_not_allowed (400)A file type that can't be published (exe, zip, and so on)Remove that file. Allowed extensions are in Files you can deploy
reserved_path (400)A path starting with admin/, v1/, or _sk/Rename the folder
hosting_disabled (409)Hosting isn't enabledRun siteon hosting enable first
subdomain_required (409)The site ID can't be used as a subdomain (too short, a reserved word, contains a brand name, already in use, and so on; the reason is in reason)siteon hosting enable --subdomain another-name
subdomain_taken / subdomain_quarantined (409)Another site uses it, or it was released less than 90 days agoChoose a different name
subdomain_change_limit (429)The subdomain was changed more than 3 times this monthWait until next month
blob_busy (409)The server is cleaning up old filesThe CLI waits and retries automatically. If it persists, wait a bit and run it again
deploy_expired / blobs_missing (409)The upload timed out (24 hours) or was interruptedRun siteon deploy again
no_previous_deploy / deploy_not_retained (409)There is no version to roll back to, or it is past the retention periodCheck retained versions with siteon deploys
insufficient_scope (403)The key lacks deploy:writeIssue a new key with that permission in the dashboard

A custom domain can't be added or doesn't become active Soon

Code / statusCauseFix
plan_required (402)The site is on FreeMove the site to a paid plan
quota_hostnames (402)The plan's slots are used up (Lite 1, Standard 3, Business 10; a www host and its bare form count as one)Remove a domain you don't use, or upgrade
invalid_hostname (400)The domain is malformedEnter it as www.example.com (no https://, no path)
hostname_blocked (400)A name commonly used for impersonationUse a different domain
hostname_reserved / hostname_in_use (409)Another account has requested or uses it / another site in your account uses itRequest it after the deadline / remove it from that site
too_many_domain_requests (429)Up to 5 requests a dayRequest it the next day
hosting_disabled (409)Hosting isn't enabledRun siteon hosting enable first
Stays "Waiting for DNS"The CNAME or TXT record is missing, mistyped, or not yet visible in DNSCompare with the records on screen and check with dig
"Failed"Not verified within 72 hours of the requestAdd it again and replace the TXT record with the new value

All meanings and fixes are in Custom domain errors and What the statuses mean.

The site still looks old after deploying

  • Wait 15 seconds, then reload
  • For CSS, JS, and images, you are seeing what the browser has cached (5 minutes for CSS and JS, 1 day for images). If your build adds hashes to file names, new files are delivered the moment you deploy
  • Run siteon deploys to check that the live version (*) is the one you just deployed

The site returns 404, 451, or 503 (hosting)

ResponseMeaningFix
404 "Not published yet"Hosting is enabled, but nothing has been deployed yetsiteon deploy
404 (shared page)No file exists at that path, or the site was deleted or the account closedCheck the path and file name (/about is about.html or about/index.html). For a custom 404 page, add 404.html
451 "This site is currently suspended"The site was suspended after an abuse report (phishing, for example) or a scanCheck the email sent to the owner. Fix the issue, then appeal. You can still deploy while suspended
503A temporary outage on the Siteon sideWait a few seconds and reload

Pages never stop being served with a 402. Delivery continues even when payment is overdue or limits are exceeded.

The dashboard or API returns 402

CodeCauseFix
upgrade_requiredYou tried to register a production (custom) domain as an allowed origin on a Free siteMove that site to a paid plan, then register it (What Free sites can register)
quota_exceededA limit was reached (CMS item count, photo storage, AI uses, the Free plan's 50 form submissions a month, and so on)Remove what you don't need, or upgrade the plan (When you reach a limit)
billing_inactivePayment is more than 8 days overdue, or the subscription has endedCheck billing in the dashboard

Form submissions return 429 quota_exceeded when the submission limit is reached (120% of the limit on paid plans). They are not saved.

Existing articles look different

The body formatting (**bold**, [text](URL), {color:…}, and auto-linking of bare URLs) also applies to articles written earlier. The most common case is ** written as literal symbols turning into bold. Search the body text for **.

Dashboard: can't sign in

After too many failed sign-in attempts, sign-in is locked for a while (5 attempts per 10 minutes per login ID and source, 50 attempts per 10 minutes per login ID). It unlocks on its own after 10 minutes. If it still fails, check for a wrong password or login ID, or whether you were removed from the site.

Dashboard: changing the password signed out other devices

This is by design. When you change your password, other devices (such as a tablet at the shop) are signed out for security. Sign in again with the new password.

Dashboard: can't upload videos or photos

  • Only MP4 (H.264) videos are accepted. iPhone .mov (HEVC) files and HEIC photos can't be played or displayed in browsers, so they aren't accepted. Changing the file extension won't help
  • On iPhone, go to "Settings → Camera → Formats → Most Compatible" so future photos and videos are saved as JPEG and MP4 (existing ones don't change)
  • Videos over 100 MB aren't accepted. Upload them to YouTube or similar and paste the link into the video block's "External URL"

"Fetch details" on a link card reads the other page's og:title and similar tags. It can't fetch them if the page has no OGP tags, requires sign-in, blocks bots, doesn't respond within 5 seconds, or isn't HTML. This isn't a fault; enter the details by hand.

This page is also available as Markdown. For AI agents, pass llms.txt (contents) or llms-full.txt (full text).