Fix: Invalid APNs Credential Error in Firebase Cloud Messaging

Fix: Invalid APNs Credential Error in Firebase Cloud Messaging
Quick answer: This error occurs when you use a production-scoped APNs Auth Key (.p8) while targeting a sandbox device token generated from an Xcode debug build. To fix it, generate an APNs key scoped for the Sandbox/Development environment in the Apple Developer Portal and upload it to the Firebase Console, or test push delivery using a TestFlight build.

Sending push notifications to iOS devices through the Firebase Admin SDK or Cloud Messaging console often fails with a generic Invalid APNs credential error. This failure happens even when your .p8 authentication key file is completely intact, the Key ID and Team ID match your Apple Developer account, and your iOS app registers cleanly for remote notifications.

Because the error message does not detail whether the token, the certificate, or the server environment was rejected, developers frequently waste hours regenerating keys or reinstalling certificates. In modern Apple developer accounts, the underlying problem almost always traces back to APNs environment mismatches.

Why this happens

Apple Push Notification service (APNs) operates two distinct gateway environments: Sandbox (api.sandbox.push.apple.com) and Production (api.push.apple.com). An iOS device token is explicitly tied to the gateway that issued it. When you build and run an app directly from Xcode onto a physical device, iOS provisions a development device token that can only be resolved by the APNs Sandbox gateway. Once an app is distributed via TestFlight or the App Store, it receives a production device token meant for the Production gateway.

When Firebase Cloud Messaging (FCM) receives your send request, it inspects the destination device token to determine which APNs gateway to target. If the token comes from an Xcode development build, FCM routes the notification to the APNs sandbox.

APNs Authentication Keys (.p8) created in the Apple Developer Portal can be scoped specifically to an environment—such as [Production] or [Sandbox]. If you configure an APNs key in the Firebase Console that only has production privileges, APNs immediately rejects any authentication handshake sent toward the sandbox endpoint. Firebase cannot establish the token-based HTTP/2 session and raises the exception Invalid APNs credential.

How to fix it

1. Verify and generate a Sandbox-scoped APNs Auth Key

If your current key is designated as Production-only, you must generate a key that supports the sandbox environment or covers development topics.

  1. Log in to the Apple Developer Portal.
  2. Navigate to Certificates, Identifiers & Profiles > Keys.
  3. Click the blue plus icon (+) to register a new key.
  4. Enter a clear key name, such as APNs Sandbox Development Key.
  5. Select the checkbox next to Apple Push Notifications service (APNs).
  6. Inspect the scoping options provided by Apple. Ensure the service includes development/sandbox permissions (or select the team-scoped key that permits sandbox delivery).
  7. Click Continue and then Register.
  8. Download the .p8 file immediately. Store it securely, as Apple allows downloading this private key only once.
  9. Note the Key ID (10 characters) and your Team ID (visible in your membership details).

2. Configure the Development Key in Firebase Console

Firebase allows projects to use APNs authentication keys for both environments. Add your development key to ensure debug builds accept incoming pushes:

  1. Open the Firebase Console and choose your project.
  2. Click the gear icon next to Project Overview and select Project settings.
  3. Navigate to the Cloud Messaging tab.
  4. Scroll down to Apple app configuration.
  5. Under your iOS app, look at your APNs Authentication Key section.
  6. If Firebase prompts for separate Development and Production credentials (or allows replacing a single-environment key), upload your new .p8 file.
  7. Enter the exact Key ID and Team ID.
  8. Save the changes.

Once configured, test sending a notification through your backend service or Admin SDK:

import firebase_admin
from firebase_admin import credentials, messaging

# Initialize Firebase Admin SDK if not already done
if not firebase_admin._apps:
    cred = credentials.Certificate("path/to/serviceAccountKey.json")
    firebase_admin.initialize_app(cred)

# Build the message payload
message = messaging.Message(
    notification=messaging.Notification(
        title="Test Push",
        body="Validating APNs sandbox delivery",
    ),
    token="<DEVICE_FCM_TOKEN>",
    apns=messaging.APNSConfig(
        headers={
            "apns-push-type": "alert",
            "apns-priority": "10",
        },
        payload=messaging.APNSPayload(
            aps=messaging.Aps(
                sound="default",
                badge=1,
            )
        ),
    ),
)

# Send through the Admin SDK
try:
    response = messaging.send(message)
    print("Successfully sent message:", response)
except Exception as error:
    print("Failed to send notification:", error)

3. Test on a Production Environment Using TestFlight

If your organization requires a strict production-only APNs key policy and does not permit uploading development credentials to your primary Firebase project, test your push pipeline against a production token instead:

  1. Open your project in Xcode.
  2. In the target’s Signing & Capabilities tab, ensure the Push Notifications capability is added.
  3. Create an archive by choosing Product > Archive.
  4. Distribute the build to TestFlight.
  5. Install the app on your physical test device via the TestFlight app.
  6. Launch the app and allow push notifications to retrieve a new APNs token and subsequent FCM token.
  7. Send your payload to this newly generated FCM token.

Because TestFlight builds use production provisioning profiles, iOS requests a production APNs token. FCM routes the push to api.push.apple.com, and your production-scoped APNs Auth Key authenticates successfully.

4. Ensure the aps-environment Entitlement Matches

If you use custom .entitlements files, confirm that Xcode is not applying a mismatched push environment entitlement during compilation. Open your <ProjectName>.entitlements file in Xcode or as raw XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>aps-environment</key>
    <string>development</string>
</dict>
</plist>

For standard Debug builds, aps-environment should resolve to development. For Release builds targeting TestFlight or App Store distribution, automatic signing sets this value to production.

How to prevent it

  • Label keys by environment in the Apple Developer Portal (for example, MyApp-APNs-Sandbox vs MyApp-APNs-Production) to prevent assigning production keys to development environments.
  • Maintain separate Firebase projects for Development/Staging and Production to isolate sandbox tokens from live production tokens.
  • Include the apns-push-type header in every APNs payload configuration when using the Firebase Admin SDK to ensure compliance with Apple’s HTTP/2 APNs requirements.
  • Do not mix simulator tokens with physical device tokens; simulators do not reliably maintain APNs gateway registrations across all notification payload types.

FAQ

Can I use the same APNs key for both Sandbox and Production?

Older team-wide APNs keys historically accepted connections to both gateways without restriction. However, keys scoped explicitly to production or created under strict enterprise policies cannot authenticate against api.sandbox.push.apple.com, triggering credentials errors when testing with local Xcode builds.

Does deleting and recreating the FCM token fix the issue?

No. The FCM registration token is derived in part from the native APNs token provided by iOS. If the native token is provisioned by the sandbox gateway, recreating or refreshing the FCM token will still return a token tied to the sandbox gateway.

Why does my Android client work fine in the same Firebase project?

Android notifications route entirely through Google’s internal Firebase Cloud Messaging pipeline and do not communicate with Apple’s servers. The Invalid APNs credential error is raised specifically by the APNs bridge when Firebase attempts to open an authenticated HTTP/2 session with Apple.

Sources & credits

Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.