Article

Handling Notification Responses from APNs

Respond to the status codes returned by the APNs servers.

Overview

Apple Push Notification service (APNs) provides a response to each POST request your server transmits. Each response contains a header with fields indicating the status of the response. If the request was successful, the body of the response is empty. If an error occurred, the body contains a JSON dictionary with additional information about the error.

If you find your device is having trouble receiving notifications, check the common problems listed in Troubleshoot Problems with Receiving Notifications.

Interpret Header Responses

Table 1 describes the meaning of the keys in the header response.

Table 1

Header keys

Header name

Value

apns-id

The same value found in the apns-id field of the request’s header. Use this value to identify the notification. If you don’t specify an apns-id field in your request, APNs creates a new UUID and returns it in this header.

:status

The HTTP status code.

Table 2 lists the possible values in the :status header of the response.

Table 2

HTTP status codes

Status code

Description

200

Success.

400

Bad request.

403

There was an error with the certificate or with the provider’s authentication token.

405

The request used an invalid :method value. Only POST requests are supported.

410

The device token is no longer active for the topic.

413

The notification payload was too large.

429

The server received too many requests for the same device token.

500

Internal server error.

503

The server is shutting down and unavailable.

Understand Error Codes

Table 3 lists the keys found in the JSON dictionary for unsuccessful requests. The JSON data might also be included in a GOAWAY frame when a connection is terminated.

Table 3

Response keys

Key

Description

reason

The error code (specified as a string) indicating the reason for the failure. For a list of possible values, see .

timestamp

The time at which APNs confirmed the token was no longer valid for the topic. This key is included only when the error in the :status field is 410.

Table 4 lists the possible error codes included in the reason key of a response’s JSON payload.

Table 4

Response error strings

Status code

Error string

Description

400

BadCollapseId

The collapse identifier exceeds the maximum allowed size.

400

BadDeviceToken

The specified device token is invalid. Verify that the request contains a valid token and that the token matches the environment.

400

BadExpirationDate

The apns-expiration value is invalid.

400

BadMessageId

The apns-id value is invalid.

400

BadPriority

The apns-priority value is invalid.

400

BadTopic

The apns-topic value is invalid.

400

DeviceTokenNotForTopic

The device token doesn’t match the specified topic.

400

DuplicateHeaders

One or more headers are repeated.

400

IdleTimeout

Idle timeout.

400

InvalidPushType

The apns-push-type value is invalid.

400

MissingDeviceToken

The device token isn’t specified in the request :path. Verify that the :path header contains the device token.

400

MissingTopic

The apns-topic header of the request isn’t specified and is required. The apns-topic header is mandatory when the client is connected using a certificate that supports multiple topics.

400

PayloadEmpty

The message payload is empty.

400

TopicDisallowed

Pushing to this topic is not allowed.

403

BadCertificate

The certificate is invalid.

403

BadCertificateEnvironment

The client certificate is for the wrong environment.

403

ExpiredProviderToken

The provider token is stale and a new token should be generated.

403

Forbidden

The specified action is not allowed.

403

InvalidProviderToken

The provider token is not valid, or the token signature can't be verified.

403

MissingProviderToken

No provider certificate was used to connect to APNs, and the authorization header is missing or no provider token is specified.

404

BadPath

The request contained an invalid :path value.

405

MethodNotAllowed

The specified :method value isn’t POST.

410

Unregistered

The device token is inactive for the specified topic.

413

PayloadTooLarge

The message payload is too large. For information about the allowed payload size, see Create and Send a POST Request to APNs.

429

TooManyProviderTokenUpdates

The provider’s authentication token is being updated too often. Update the authentication token no more than once every 20 minutes.

429

TooManyRequests

Too many requests were made consecutively to the same device token.

500

InternalServerError

An internal server error occurred.

503

ServiceUnavailable

The service is unavailable.

503

Shutdown

The APNs server is shutting down.

Listing 1 shows a sample response for a successful push request.

Listing 1

A successful response

HEADERS
  + END_STREAM
  + END_HEADERS
  apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
  :status = 200

Listing 2 shows a sample response when an error occurs.

Listing 2

An error response

HEADERS
  - END_STREAM
  + END_HEADERS
  :status = 400
  content-type = application/json
  apns-id: <a_UUID>
DATA
  + END_STREAM
  { "reason" : "BadDeviceToken" }

Troubleshoot Problems with Receiving Notifications

During testing, if you find that your test devices are not receiving push notifications sent by your provider server, examine the following possible causes:

  • Make sure that your provider server has an up-to-date device token for your test device. Each time your app launches, it should request its current token and forward that token to your provider server. You should also implement the appropriate failure handler methods to determine if APNs reported an error. See Registering Your App with APNs.

  • Check for errors returned by APNs. When failures occur, APNs reports an appropriate error back to your provider server. See Handle the Response from APNs.

  • Make sure you included the apns-push-type key in your request headers. This key is required starting in watchOS 6. The absence of this key may delay the delivery of notifications, or prevent their delivery altogether. See Table 1.

  • Check to see if you are sending requests to the same device too quickly. APNs queues only one notification at a time for each device, and the device must acknowledge receipt of the notification before APNs dequeues it. If you send multiple notification requests in a very short period of time, each new request might overwrite the previous request.

  • Check to see if silent notifications are being throttled. APNs sends a limited number of silent notifications—notifications with the content-available key—per day. In addition, if the device has already exceeded its power budget for the day, silent notifications are not sent again until the power budget resets, which happens once a day. These limits are disabled when testing your app from Xcode. See Pushing Background Updates to Your App.

  • Check the firewall settings of your server and devices. To send notifications, your provider server must allow inbound and outbound TCP packets over port 443 for HTTP/2 connections, or port 2195 when using the binary interface. Devices connecting to APNs over Wi-Fi need to allow inbound and outbound TCP packets over port 5223, falling back to port 443 if port 5223 is unavailable. Computers running macOS must also allow inbound and outbound TCP traffic on port 80.

  • Verify that you aren't spamming the device. If you send too many notifications to the same device within a short timespan, APNs may treat it as a denial-of-service attack and temporarily block your server from sending notifications.

If your provider server is unable to connect to APNs, examine the following possible causes:

  • Make sure you have the needed certificates installed on your provider server. If your provider server doesn't have the proper certificates for TLS/SSL validation, it cannot connect to APNs. For certificate-based connections, your provider server must also have the certificate you obtained from Apple. See Establishing a Certificate-Based Connection to APNs.

  • Check how often your provider server connects to APNs. If your provider server uses the legacy binary interface and opens and closes its connection to APNs repeatedly, APNs may treat it as a denial-of-service attack and temporarily block your server from connecting.

You can verify the TLS handshake between your provider server and APNs by running the OpenSSL s_client command from your server, as shown in Listing 3. This command can also show if your TLS/SSL certificates are expired or revoked.

Listing 3

Verifying the TLS handshake

$ openssl s_client -connect api.development.push.apple.com:443 -cert YourSSLCertAndPrivateKey.pem -debug 
-showcerts -CAfile server-ca-cert.pem

See Also

Server Tasks

Generating a Remote Notification

Send notifications to the user’s device with a JSON payload.

Sending Notification Requests to APNs

Transmit your remote notification payload and device token information to APNs.

Pushing Background Updates to Your App

Deliver notifications that wake your app and update it in the background.