Strict version mode
Strict version mode is a per-product setting that rejects events whose source_version isn’t pre-registered. Off by default. Turn it on when your team wants to lock down which versions can produce data.
What problem it solves
By default, Beacon auto-registers any new source_version the first time an event arrives with it. That’s friction-free for onboarding, but it has a long-tail cost: a bug in your SDK integration that emits a malformed version (random hash, leaked git SHA, empty-after-trim string) silently pollutes your version list. Once it’s there, the bad version appears in every selector and filter until you merge or archive it.
Strict mode flips the default: only registered versions are accepted; garbage is rejected at ingestion and never enters the list.
When to turn it on
Turn it on once your release process is disciplined enough to always register a new version before deploying it. Examples:
- Your CI/CD pipeline calls
/v1/version-registrations(or a human registers via the portal) as part of the release. - Your team has a small set of versions that ship deliberately (e.g., desktop or mobile app versions, not high-cardinality web build hashes).
Skip it — or turn it off — if your source_version values are auto-generated (build hashes, branch names, CI run IDs) where pre-registration would be impractical.
How to enable
In the sidebar, expand Settings → Products, click the product, and find the Strict version mode toggle on the product info card. Flipping it on shows a confirmation modal explaining the consequence:
Any event whose
source_versionis not pre-registered will be rejected withUNREGISTERED_VERSION.
Click Enable strict mode to confirm. Turning it back off applies immediately without confirmation (the action is non-destructive).
Requires the manage_products permission. Users without it see the current state but not the toggle.
What gets rejected
When strict mode is on, the following events are rejected:
- Unregistered version —
source_versionnot registered for this product →UNREGISTERED_VERSION. - Archived version — version exists but its
statusis anything other thanactive→ alsoUNREGISTERED_VERSION. Archived versions are deliberately removed from the accepted set.
What is NOT rejected
- Null
source_version. The Identify call (Actor Identity) accepts a nullsource_versionfrom SDKs that aren’t configured with one. Strict mode validates supplied versions, not the absence of one. - Product validation.
UNRECOGNIZED_PRODUCTis enforced regardless of strict mode — that’s a separate, always-on gate. - Allowlists. Allowlist rejection (
ALLOWLIST_REJECTED) is independent. Strict mode and allowlists answer different questions; both can be on, both can be off, in any combination.
How rejections surface per endpoint
| Endpoint | Response when version is rejected |
|---|---|
POST /v1/events (batch) | 207 with the bad events appearing in Invalid Events under UNREGISTERED_VERSION. Good events in the same batch are still accepted. |
POST /v1/events/sessions | 422 JSON, the session is not created. |
POST /v1/events/exceptions | 422 JSON, the exception is not recorded. |
POST /v1/actors/identify | 422 JSON, the actor identity is not recorded. |
SDK behavior — events are LOST on permanent rejection
Strict-mode rejection is not transient — the version won’t suddenly register itself. All three SDKs treat UNREGISTERED_VERSION and 422 responses as terminal: dropped, no retry, no queue replay. (.NET and C++ requeue genuinely transient failures via local SQLite; JS only requeues 429. None requeue strict-mode rejection.)
If you forget to register a version before deploying, events emitted between deploy and registration are permanently lost. Strict mode trades a discipline tax for clean data.
Recommended workflow
- CI or release tooling calls
POST /v1/version-registrationsfor the new version (with an optionalrelease_date) before the new build is deployed. - Deploy.
- Optional — verify the new version appears in the Versions page for the product.
Common questions
My SDK is sending events but they’re not showing up.
Check Invalid Events for UNREGISTERED_VERSION dead letters. If you see them, register the version on the product’s Versions page. Future events will be accepted; the rejected ones are gone.
I archived a version by mistake.
Open the version on the Versions page and un-archive it. Re-activating restores its status = 'active' and ingestion resumes.
Can I turn strict mode on for some events and off for others? The toggle is per-product, not per-event. If different parts of your application have different governance needs, model them as separate products with separate strict-mode settings.
Does strict mode apply retroactively? No. It only governs events being ingested now. Historical events ingested under non-strict mode keep their auto-registered versions in the version list. To clean those up, use the merge or archive affordance on the Versions page.