Production APNs rejects a valid production device token with BadEnvironmentKeyInToken (newly released app)

My app was approved and released on the App Store on Aug 19, 2026 (bundle ID br.com.stackads.app, Team ID MSGM29Z362). Push notifications do not work on the production/App Store/TestFlight build. Android via FCM works fine; only iOS production APNs fails. It has been more than 48 hours since release.

I captured the raw APNs device token directly from application(_:didRegisterForRemoteNotificationsWithDeviceToken:) in a production (App Store distribution) build (aps-environment = production, verified in the built .ipa entitlements). Sending directly to APNs with a token-based .p8 auth key (Key ID VXXXXXXX, Team ID MSGM29Z362), apns-topic br.com.stackads.app, apns-push-type alert, returns:

  • api.push.apple.com (production): HTTP 403 {"reason":"BadEnvironmentKeyInToken"}
  • api.sandbox.push.apple.com (sandbox): HTTP 400 {"reason":"BadDeviceToken"}

The provider (JWT) authentication succeeds (I get a device-token error, not an auth error), so the key is valid. The App ID has the Push Notifications capability enabled. The token is freshly registered (confirmed identical between the didRegister callback and getAPNSToken).

Why does the production APNs endpoint reject a valid production device token for this App ID with BadEnvironmentKeyInToken? Is there something pending in the production APNs provisioning for a newly released App ID?

BadEnvironmentKeyInToken points to the .p8 key, not to your token or App ID. Since Apple added team-scoped and topic-specific keys, every APNs key has an Environment setting (Sandbox, Production, or Sandbox & Production), and you can't change it after the key is created. Your results match a sandbox-only key: production refuses the key (403), while sandbox accepts the key but rejects your production token (400 BadDeviceToken).

Fix:

  1. Go to Certificates, Identifiers & Profiles > Keys, open the key and check its APNs environment.
  2. If it is Sandbox only, create a new key with APNs enabled, click Configure and choose Environment "Sandbox & Production" (or "Production"). For Key Restriction, pick Team Scoped or your bundle ID.
  3. Update the Key ID and .p8 on your server (and in Firebase, if you use it), wait a few minutes, then resend to api.push.apple.com.

To check the token without involving the key, you can send one push using a Production APNs certificate (.p12) instead. I'm the developer of Push Notification Tester, a free Mac app that does exactly this: https://apps.apple.com/us/app/push-notification-tester/id1516154713