Troubleshooting
Common problems, what causes them, and how to fix them.
Find your symptom, read the cause, apply the fix. Most of what looks like a bug is one of about ten things.
Data isn’t showing up
“I don’t see any data”
Work down this list in order — it’s roughly ordered by how often each one is the answer.
Is the project still in setup? Events are not stored until you press Go Live. In setup status the collector accepts your events, shows them in the onboarding test screen, and drops them. Nothing lands in reports. Check the onboarding test screen: if events appear there but nowhere else, this is your answer. See Going live.
Are you testing from localhost? Debug mode turns on automatically for local hosts, and debug events are never counted:
localhost127.*10.*192.168.*172.16.*through172.31.**.local0.0.0.0
Deploy to a real domain, or watch the onboarding test screen, which shows debug traffic live.
Is the snippet actually on the page? Open devtools, go to the Network tab, and reload. You’re looking for a request to /e on the collector. No request means the snippet isn’t running — check that it’s in the deployed HTML, not blocked by a CSP, and not stripped by your framework’s build.
Don’t trust a 2xx as proof your key is valid. Unknown and revoked keys deliberately return the same 2xx response as valid ones, so the API can’t be used to guess which keys exist. A successful request tells you the network path works, nothing more. Re-copy your public key from Settings → Install and compare it character for character with what’s in your page.
Is the project paused? Paused projects accept events and drop them. Check your project status.
“I can’t go live”
Go Live requires all of these:
- A verified email. Check your inbox, or resend from the banner in your account settings.
- An active subscription or a running trial. See Account and billing.
- Your analytics store finished provisioning. Right after you create a project this takes a moment and shows as “setting up analytics.” It resolves on its own — wait and refresh.
Attribution and sources
“My source data is missing or says unattributed”
Cause: the domain you’re serving from isn’t in Settings → Data → Domains.
That list is an origin allowlist. Events from an origin that isn’t on it are still accepted — you won’t lose the traffic — but they’re marked unattributed, and their referrer, UTM, and attribution fields are stripped.
Fix: add every domain you serve from. Both yourproduct.com and app.yourproduct.com if you run a marketing site and an app. Apex and subdomains are distinct entries.
Fixing the list doesn’t retroactively repair events that were already stripped — the fields were never stored. From then on, attribution works.
“Stripe / Google shows up as a traffic source”
Cause: your visitor left your site to a payment or OAuth provider and came back, so that provider is the referrer on the return trip. It’s real, but it isn’t acquisition.
Fix: add those hosts to Settings → Data → Ignored referrers.
Conversions and events
“My conversion count is zero”
Cause 1 — the name doesn’t match. Compare the exact event name in Settings → Tracking against what actually appears in the events log. sign_up and signup are different events. So are Signup and signup.
Fix: either change what you send, or add an alias mapping the incoming name onto your configured name. Aliases apply retroactively, so a typo you’ve been sending for a month is repaired the moment you add the alias. See Event aliases.
Cause 2 — you configured a page conversion and the path doesn’t match. Page conversions are a prefix match on the path. /welcome matches /welcome and /welcome/step-2. It does not match /app/welcome.
Cause 3 — you’re firing the event too early. Fire the conversion event only after the action truly succeeds, not when the button is clicked. A form submit that fails validation shouldn’t count.
“Pageviews look inflated or too low in my SPA”
Cause: the SDK hooks pushState and replaceState and deduplicates by path + search. That covers most routers. It doesn’t cover hash-based routing, or a custom router that changes the view without touching history.
Fix: call lp.track_pageview() manually on your route change. See SDK reference.
If pageviews look inflated instead, look for a router that fires both pushState and a manual track_pageview() for the same navigation, or a component that re-initializes on every render.
“Revenue shows 0”
Cause: you’ve never sent $revenue, so that column doesn’t exist for your project. Empty columns are dropped.
This is not an error. Send revenue and the column appears. See Revenue tracking.
Dashboards and insights
“An insight card is empty”
Cause: you broke it down by a dimension your site never sends. If no event ever carried a UTM campaign, the column doesn’t exist for your project and there’s nothing to group by.
Fix: either start sending that data — tag your campaign links with UTM parameters, for example — or break down by a dimension you actually have. See Insights and Data model.
“Times look shifted”
Cause: the Local/UTC toggle changes display only. Buckets are always computed in UTC.
Switching to Local relabels the axis without recomputing which events fall in which bucket, so on a non-UTC timezone the labels appear offset relative to the real bucket boundaries. This is expected. If you need labels and boundaries to agree exactly, view in UTC.
Alerts and webhooks
“My alert never fires”
Cause 1 — interval gating. A rule is not re-queried faster than max(60 seconds, window ÷ 4). A 24-hour window is therefore checked at most every ~6 hours. If you just created the rule, it may simply not have run yet.
Cause 2 — it’s already firing. Alerts are edge-triggered: one notification when the condition starts being true, one when it recovers. There are no repeats while it stays firing. If you’re waiting for a second notification, you won’t get one until it recovers and trips again.
“My alert fires too much”
Cause: a very short window on a low-traffic site. A 5-minute window will trip during any normal quiet period — nights, weekends, a slow Tuesday. That’s the rule working as written.
Fix: widen the window until it reflects a real problem rather than ordinary variance.
See Alerts.
“My webhook doesn’t deliver”
Check each requirement:
| Requirement | Detail |
|---|---|
| Scheme | https only |
| Host | Must be publicly reachable. localhost, LAN, and private IPs are rejected |
| Timeout | 10 seconds |
| Redirects | Not followed |
| Success | Any non-2xx counts as failed |
Fix: use Send test to trigger a delivery on demand, and check Recent activity for the delivery-failed flag.
The most common causes are a tunnel that has expired, an endpoint returning 3xx expecting the redirect to be followed, and a handler doing slow work inline instead of queueing and returning 200 immediately.
See Alert webhooks.
Still stuck?
Two things resolve most of what’s left:
- Open the events log and look at the raw event. What’s actually in
event_name,path,user_id, andpropertiesusually settles the question immediately. - Re-read Data model. Numbers that look wrong are often correct under a definition you weren’t expecting — actors versus visitors is the usual one.