# Troubleshooting

Source: https://pushary.com/docs/web-push/troubleshooting
Last updated: 2026-05-11

> Common issues and solutions for Pushary push notifications

## Common Issues [#common-issues]

### Notifications Not Working [#notifications-not-working]

If notifications aren't appearing, check the following:

#### 1. Permission Not Granted [#1-permission-not-granted]

**Problem:** User hasn't granted notification permission.

**Solution:**

```typescript
if (Notification.permission !== 'granted') {
  await pushary.promptForPermission()
}
```

Check permission status:

```typescript
console.log('Permission:', Notification.permission)
```

#### 2. Push Not Supported [#2-push-not-supported]

**Problem:** Browser doesn't support push notifications.

**Solution:**

```typescript
import { isPushSupported } from '@pushary/sdk'

if (!isPushSupported()) {
  console.log('Push notifications not supported')
  // Show alternative notification method
}
```

#### 3. Service Worker Not Registered [#3-service-worker-not-registered]

**Problem:** Service worker file not found or not registered.

**Solution:**

* Verify `pushary-sw.js` is in your public directory
* Check service worker registration in DevTools > Application > Service Workers
* Ensure the service worker path is correct:

```typescript
createPushary({
  siteKey: 'pk_xxx',
  serviceWorkerPath: '/pushary-sw.js', // Must be at root
})
```

#### 4. HTTPS Required [#4-https-required]

**Problem:** Push notifications only work on HTTPS.

**Solution:**

* Deploy to HTTPS domain
* Use `localhost` for local development (HTTPS not required)
* Don't test on `192.168.x.x` or other local IPs

***

## iOS Safari Issues [#ios-safari-issues]

### iOS Safari Not Working [#ios-safari-not-working]

**Problem:** Notifications not showing on iOS Safari.

**Requirements:**

* iOS 16.4 or later
* Safari 16.4 or later
* PWA installed to home screen (notifications don't work in browser tab)
* User must grant permission

**Solution:**

1. Create a web app manifest:

```json
{
  "name": "Your App",
  "short_name": "App",
  "display": "standalone",
  "icons": [
    {
      "src": "/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}
```

2. Add to HTML:

```html
<link rel="manifest" href="/manifest.json">
<meta name="apple-mobile-web-app-capable" content="yes">
```

3. User must:
   * Open website in Safari
   * Tap Share button
   * Tap "Add to Home Screen"
   * Open app from home screen
   * Grant notification permission

***

## Subscription Issues [#subscription-issues]

### Subscriber Not Showing in Dashboard [#subscriber-not-showing-in-dashboard]

**Problem:** User subscribed but doesn't appear in dashboard.

**Debugging:**

1. Check browser console for errors
2. Verify subscription was successful:

```typescript
createPushary({
  siteKey: 'pk_xxx',
  onSubscribe: (subscription) => {
    console.log('Subscribed successfully:', subscription.endpoint)
  },
  debug: true, // Enable debug logging
})
```

3. Check network tab for failed API calls
4. Verify site key is correct

### Subscription Endpoint Changed [#subscription-endpoint-changed]

**Problem:** Browser subscription endpoint changed after reinstalling browser.

**Solution:** The SDK automatically handles this via the `subscription-change` endpoint. If issues persist:

1. Have user unsubscribe and resubscribe:

```typescript
await pushary.unsubscribe()
await pushary.subscribe()
```

***

## Permission Issues [#permission-issues]

### Permission Denied [#permission-denied]

**Problem:** User clicked "Block" on permission prompt.

**Solution:**

* Permission denial is permanent per domain
* User must manually reset in browser settings:
  * **Chrome:** Settings > Privacy > Site Settings > Notifications
  * **Firefox:** Settings > Privacy > Permissions > Notifications
  * **Safari:** Settings > Websites > Notifications

**Best practice:** Don't prompt immediately on page load. Use `autoPrompt: false` and ask at appropriate time:

```typescript
createPushary({
  siteKey: 'pk_xxx',
  autoPrompt: false,
})

// Prompt after user shows interest
button.addEventListener('click', async () => {
  await pushary.promptForPermission()
})
```

### Permission Already Granted But Not Subscribed [#permission-already-granted-but-not-subscribed]

**Problem:** Permission is granted but subscription missing.

**Solution:**

```typescript
if (Notification.permission === 'granted') {
  await pushary.subscribe()
}
```

***

## API Issues [#api-issues]

### 403 Error: API Access Required [#403-error-api-access-required]

**Problem:** Getting 403 errors when calling server API endpoints.

**Error:**

```json
{
  "error": "API access requires Starter plan or higher",
  "message": "Upgrade your plan to access the server API"
}
```

**Solution:**

* The server API (`/api/v1/server/*`) requires Starter plan or higher
* Upgrade your plan at `/dashboard/settings?tab=billing`
* Free plan only supports client-side SDK integration

### 429 Error: Rate Limit Exceeded [#429-error-rate-limit-exceeded]

**Problem:** Too many API requests.

**Solution:**

* Check rate limits for your plan:
  * Free: 100 req/min
  * Starter: 200 req/min
  * Growth: 500 req/min
  * Enterprise: 1000 req/min

* Implement exponential backoff:

```typescript
async function sendWithRetry(data, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await pushary.notifications.send(data)
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)))
        continue
      }
      throw error
    }
  }
}
```

### 404 Error: Campaign Not Found [#404-error-campaign-not-found]

**Problem:** Campaign ID not found.

**Solution:**

* Verify campaign ID is correct
* Check that campaign belongs to the correct site
* Ensure you're using the full API key, not just the site key

***

## Debugging Tips [#debugging-tips]

### Enable Debug Mode [#enable-debug-mode]

Enable detailed logging:

```typescript
createPushary({
  siteKey: 'pk_xxx',
  debug: true,
})
```

### Check Service Worker Console [#check-service-worker-console]

1. Open DevTools
2. Go to Application > Service Workers
3. Click "Service Worker" link to open its console
4. Look for push/notification events

### Verify VAPID Keys [#verify-vapid-keys]

Check if site has VAPID keys configured:

```typescript
// In service worker
self.addEventListener('push', (event) => {
  console.log('Push received:', event.data?.text())
})
```

### Test Push Manually [#test-push-manually]

Use browser DevTools to test push:

1. Open DevTools > Application > Service Workers
2. Click "Push" to send test notification
3. Enter test payload and click "Send"

***

## Common Error Messages [#common-error-messages]

### "Failed to register service worker" [#failed-to-register-service-worker]

**Causes:**

* Service worker file not found
* HTTPS required (except localhost)
* Service worker scope issues

**Solution:**

* Ensure `pushary-sw.js` is in public root directory
* Check browser console for specific error
* Verify file is accessible at `/pushary-sw.js`

### "Permission denied in system prompt" [#permission-denied-in-system-prompt]

**Causes:**

* User clicked "Block"
* Browser blocked auto-prompts

**Solution:**

* User must manually reset permission in browser settings
* Don't spam permission prompts (browsers may auto-block)

### "Subscription endpoint is invalid" [#subscription-endpoint-is-invalid]

**Causes:**

* Subscription expired or revoked
* Browser cleared data

**Solution:**

```typescript
try {
  await pushary.subscribe()
} catch (error) {
  console.error('Subscription failed:', error)
  // Re-prompt user
  await pushary.promptForPermission()
}
```

***

## Getting Help [#getting-help]

If you're still experiencing issues:

1. Check browser console for errors
2. Enable debug mode in the SDK
3. Verify your plan has required features
4. Contact support at [business@pushary.com](mailto:business@pushary.com) with:
   * Browser and OS version
   * Error messages from console
   * Site key (not full API key)
   * Steps to reproduce