Troubleshooting
Common errors and how to fix them.
HTTP errors
401 Unauthorized
Cause: Missing, invalid, or revoked API key.
Fix:
- Verify
Authorization: Bearer ft_...header is set. - Copy a new key from Environment → API keys → Create key (old full value cannot be recovered).
- Check the key status is still Active (not Revoked).
SDK behavior: Clears cache and stops SSE stream. Call init() again after fixing the key.
403 Forbidden
Cause: API key scope violation.
| Scenario | Message pattern |
|---|---|
Test key (ft_test_) from non-localhost | Off-loopback origin |
Test key from LAN IP (10.x, 172.16-31.x, 192.168.x) | Same cause: RFC1918 is not loopback |
Live key (ft_live_) without deploy access | Account cannot use staging/production |
| Inactive subscription | Live keys disabled |
Fix:
| Scenario | Action |
|---|---|
| Local dev from localhost | Use ft_test_ from development |
Phone-on-WiFi (http://192.168.x.x:3000) | Free plan: use localhost on the same machine, or Upgrade plan → Add staging / Add production → ft_live_ key |
| Deployed app | Click Add staging or Add production in the project sidebar; create an ft_live_ key under API keys; use server SDK |
| SSR with test key | Add Origin: http://localhost:<port> on custom fetch, or use live key |
.local | Not treated as localhost. Use a live key. |
The SDK logs a one-time console.warn with the API error message.
404 Feature not found
Cause: On GET /v1/features/:key only, for an unknown key or a disabled feature.
Fix:
- Check the key spelling (case-sensitive).
- Enable the feature on Feature definitions (row menu → Enable), or set an override on Environment → Overrides.
- Use
GET /v1/featuresbulk fetch. Disabled features are silently omitted, not errored.
SDK: Missing keys return isEnabled() === false and getValue() === undefined.
400 Bad Request
Cause: Invalid type or deprecated query param on GET /v1/features.
Fix: Use only boolean, string, number, json for type; true or false for deprecated.
304 Not Modified
Not an error. Features unchanged since the last ETag. SDK keeps existing cache.
429 Too Many Requests
Cause: Account usage limit exceeded for the current period.
Fix: Wait for the next period or contact support. Reduce unnecessary refresh() calls; unchanged data returns 304 automatically.
SDK issues
Features not updating after dashboard toggle
| Check | Action |
|---|---|
| SSE connected? | Ensure stream is not "off"; check network tab for /v1/features/stream |
Using stream: "off"? | Expect poll-based or tab-focus refresh. Default poll is 30s; use pollInterval or refresh() for faster checks |
| Wrong environment? | API key must match the environment you toggled |
| Override vs default? | Confirm effective value changed for that environment |
| Tab in background? | Refocus tab or call refresh() (poll timer pauses while hidden) |
Typical latency: seconds with SSE; up to poll interval (default 30s) with stream: "off"; up to ~60s worst case without stream or poll.
init() throws on first load
Cause: Network failure or invalid key on first fetch.
Fix: Verify API key, network, and origin scope (test key on localhost). Check browser console for error details.
Stale values on server
Cause: Shared FeatureToggleServer without refresh().
Fix: await ft.refresh() before reads, or use per-request instances.
Deprecated warning in console
Expected. One-time warning per deprecated key. Migrate to inFavorOf replacement when set.
Stream keeps reconnecting
Cause: Network interruption, proxy timeout, or close() called.
Fix: SDK uses exponential backoff automatically. Check corporate proxies allow long-lived SSE to api.featuretoggle.com.
Dashboard issues
Cannot add staging/production
Cause: The account may not have deploy access yet.
Fix: On the free plan, click Add staging or Add production and choose Upgrade plan, or open Billing in the sidebar. Contact support if you already have a paid plan and still cannot add environments.
Cannot delete development environment
By design. development is permanent and seeded on project create.
Feature key cannot be edited
By design. Keys are immutable after create. Create a new feature on Feature definitions, then Deprecate the old one (optionally choose a Replacement feature).
Type cannot be changed
Cause: Active API keys or environment overrides exist.
Fix: Revoke API keys and choose Use default on overrides, or create a new feature with the correct type.
Direct API debugging
# Bulk fetch
curl -sD - https://api.featuretoggle.com/v1/features \
-H "Authorization: Bearer YOUR_KEY"
# Conditional fetch
curl -sD - https://api.featuretoggle.com/v1/features \
-H "Authorization: Bearer YOUR_KEY" \
-H 'If-None-Match: "1"'
# Single feature
curl -s https://api.featuretoggle.com/v1/features/my-feature \
-H "Authorization: Bearer YOUR_KEY"
# SSE stream
curl -N https://api.featuretoggle.com/v1/features/stream \
-H "Authorization: Bearer YOUR_KEY" \
-H "Accept: text/event-stream"Look for ETag and status code in response headers.
Still stuck?
- Confirm environment matches the key prefix (
ft_test_→development,ft_live_→stagingorproduction). - Review Security for key placement.
- Review Caching and syncs for expected refresh behavior.