How to fix Azure Notification Hubs push delivery failures

Understanding Azure Notification Hubs Push Delivery

Azure Notification Hubs provides a scaled-out push notification engine that enables you to send notifications to any platform — iOS, Android, Windows, Kindle — from any back-end. Push delivery failures are particularly frustrating because they are silent: the sender gets a success response, but the notification never reaches the device. The failure happens downstream at the Platform Notification Service (PNS) level, and diagnosing it requires understanding the multi-hop delivery pipeline.

This guide covers every stage where push delivery can fail, from credential misconfiguration to PNS-level issues, with exact diagnostic steps and code examples.

Push Notification Delivery Pipeline

  1. Device registers with the Platform Notification Service (APNs, FCM, WNS)
  2. Device sends the PNS handle to your back-end
  3. Back-end creates a registration in Azure Notification Hubs
  4. Back-end sends notification to Notification Hubs
  5. Notification Hubs forwards to the PNS
  6. PNS delivers to the device

Failures can occur at steps 3, 5, or 6 — and each requires different diagnostic approaches.

Credential Misconfiguration

PNS Authentication Error

The most common cause of push delivery failure is incorrect PNS credentials configured in the Notification Hub.

Platform Credential Type Where to Get It
APNs (iOS) Certificate (.p12) or Token (.p8) Apple Developer Portal > Certificates, Identifiers & Profiles
FCM (Android) Server Key or FCM v1 Service Account JSON Firebase Console > Project Settings > Cloud Messaging
WNS (Windows) Package SID + Security Key Windows Dev Center > App Management > WNS/MPNS

APNs-Specific Issues

  • Production vs Sandbox: You must maintain separate hubs for production and sandbox environments. Uploading a sandbox certificate to a production hub (or vice versa) silently drops all notifications
  • Certificate expiration: APNs certificates expire annually. Renew before expiration
  • Wrong certificate type: Publishing certificate must be a push notification certificate, not a development certificate

FCM-Specific Issues

  • Wrong server key: The key in Azure must match the key in Firebase Console
  • FCM v1 migration: Legacy FCM APIs are deprecated; migrate to FCM v1 with service account credentials
  • Project ID mismatch: The Firebase Project ID on the client must match the project whose server key is configured in Azure

Verification

Use the Test Send feature to quickly verify credentials:

Portal > Notification Hub > Support + Troubleshooting > Test Send

If Test Send returns a PNS Authentication Error, the credentials are definitely wrong.

Registration Issues

Missing or Stale Registrations

Notifications can only be delivered to devices with valid registrations. Common issues:

  • No registration: Device never registered or registration was cleaned up
  • Stale PNS handle: Device token/handle changed but registration wasn’t updated
  • Expired registration: Registrations expire after 90 days of inactivity
// C#: Create or update a registration
var registration = new AppleRegistrationDescription(deviceToken);
registration.Tags = new HashSet<string> { "userId:12345", "news" };

// Use CreateOrUpdateRegistrationAsync to handle stale registrations
var result = await hub.CreateOrUpdateRegistrationAsync(registration);

Invalid Registrations

When Notification Hubs sends a notification and the PNS returns an invalid handle error, the registration is automatically removed. This is correct behavior — but if your app doesn’t re-register, the device stops receiving notifications permanently.

Viewing Registrations

// C#: List all registrations (for debugging)
var allRegistrations = await hub.GetAllRegistrationsAsync(0);
foreach (var reg in allRegistrations)
{
    Console.WriteLine($"ID: {reg.RegistrationId}, Tags: {string.Join(",", reg.Tags ?? new HashSet<string>())}");
}

Tag and Tag Expression Mismatches

Notifications are routed to devices based on tags. If the send call uses a tag expression that doesn’t match any registered devices, the notification goes nowhere — and this is reported as a success.

// Device registered with tag: "interests:sports"
// Sending to tag: "interests:news"
// Result: 0 devices matched, notification silently dropped

// Fix: Verify tags before sending
var outcome = await hub.SendAppleNativeNotificationAsync(
    payload, "interests:sports");  // Must match registered tags

// Tag expression examples
"tag1 && tag2"     // Both tags required
"tag1 || tag2"     // Either tag
"!tag1"            // Not tag1
"(tag1 || tag2) && tag3"  // Complex expression (max 20 tags)

Using Test Send for Debugging

The EnableTestSend feature provides detailed per-device delivery feedback, but with limitations:

  • Throttled to 10 devices and 10 sends per minute
  • Only for debugging — do NOT use in production
// Enable test send
var hub = NotificationHubClient.CreateClientFromConnectionString(
    connectionString, hubName, enableTestSend: true);

var outcome = await hub.SendWindowsNativeNotificationAsync(toast);

// Check results
Console.WriteLine($"State: {outcome.State}");  // Enqueued, DetailedStateAvailable, etc.

if (outcome.Results != null)
{
    foreach (var result in outcome.Results)
    {
        Console.WriteLine($"Platform: {result.ApplicationPlatform}");
        Console.WriteLine($"Registration: {result.RegistrationId}");
        Console.WriteLine($"Outcome: {result.Outcome}");
        // Outcome values: "The Notification was successfully sent to the Push Notification System"
        // or error details like "WnsForbidden", "GcmInvalidRegistration", etc.
    }
}

Per Message Telemetry

For production debugging without the Test Send limitations, use Per Message Telemetry (available on Standard tier only):

// REST API: Send with telemetry enabled
POST https://{namespace}.servicebus.windows.net/{hub}/messages?api-version=2016-07

Headers:
  Authorization: SharedAccessSignature sr=...
  ServiceBusNotification-Format: apple  // or gcm, windows
  ServiceBusNotification-DeviceHandle: {token}  // Target specific device
  
// Track delivery via:
GET https://{namespace}.servicebus.windows.net/{hub}/messages/{messageId}?api-version=2016-07

PNS Throttling and Message Coalescing

Throttling

PNS services (APNs, FCM, WNS) have their own rate limits. When Notification Hubs exceeds these limits:

  • The PNS returns a throttling response with exponential back-off
  • Notification Hubs retries with back-off
  • If the PNS is unreachable for 30 minutes, messages are permanently dropped

Message Coalescing

When a device is offline, PNS services store only the most recent notification for delivery when the device comes back online. Previous notifications are discarded. This is by design:

  • APNs: Stores one notification per app (coalescing)
  • FCM: Stores up to 100 messages, collapsing by collapse key
  • WNS: Stores one notification per tile/toast type

Shared Access Signature Issues

Using the wrong SAS policy is a common authentication error:

Use Case SAS Policy
Device registration (client) DefaultListenSharedAccessSignature
Sending notifications (back-end) DefaultFullSharedAccessSignature

Using the Listen policy to send notifications results in 403 Forbidden errors.

Template Registration Issues

// Template for cross-platform notifications
// APNs template
{
    "aps": {
        "alert": "$(message)"
    }
}

// FCM template
{
    "data": {
        "message": "$(message)"
    }
}

// Send once, delivers to all platforms
var properties = new Dictionary<string, string>
{
    { "message", "Breaking news!" }
};
await hub.SendTemplateNotificationAsync(properties, "news");

Template format must exactly match the PNS-required JSON structure. Malformed templates cause silent delivery failures.

Monitoring and Telemetry

Navigate to Portal > Notification Hub > Overview to monitor:

  • Incoming Messages: Notifications received by the hub
  • Registration Operations: Create, update, delete counts
  • Successful Notifications: Notifications accepted by PNS
  • PNS Errors: Errors returned by the PNS

Note: Telemetry features require Standard tier. Free and Basic tiers return HTTP 403 when accessing telemetry APIs.

Hub Name and Namespace Verification

A subtle but common issue is using the wrong hub name or namespace. Verify that the notification hub name used in:

  • Client registration code
  • Back-end send code
  • PNS credential configuration

…all refer to the exact same hub. Typos in hub names cause notifications to go to a different hub entirely.

Prevention Best Practices

  • Use Standard tier for production — Required for telemetry, diagnostics, and per-message tracking
  • Maintain separate hubs for APNs sandbox and production — Mixing causes silent failure
  • Treat ServiceBusClient types as singletons — Don’t create new instances per send
  • Re-register on every app launch — Ensures PNS handle and tags are current
  • Monitor PNS credential expiration — Set calendar reminders for certificate renewal
  • Use Test Send during development — Catches configuration issues early
  • Use templates for cross-platform — Single send call instead of per-platform sends
  • Implement device re-registration on PNS handle change — Handles token refresh gracefully

Summary

Azure Notification Hubs push delivery failures are typically caused by credential misconfiguration (wrong PNS keys/certificates), registration issues (stale handles, missing registrations), tag mismatches (sending to tags no device has registered for), or PNS-level throttling and coalescing. The Test Send feature is the fastest way to determine if the issue is credentials, registrations, or PNS-level. For production debugging, Per Message Telemetry on Standard tier provides detailed delivery tracking. Always maintain separate hubs for APNs sandbox and production environments.

For more details, refer to the official documentation: Quickstart: Set up push notifications in a notification hub.

Leave a Reply