If you’re having trouble with the SDK, here are some basic steps to troubleshoot your problems, and solutions to some known issues.

Basic troubleshooting steps

  1. Make sure your app meets our prerequisites: Attempting to use our SDK in an environment that doesn’t match our supported versions may result in build errors.
  1. Update to the latest version: When troubleshooting problems with our SDKs, we generally recommend that you try updating to the latest version. That helps us weed out issues that might have been seen in previous versions of the SDK.
  2. Try running CIO SDK Tools: Our SDK Tools include a doctor command that can help diagnose problems with your SDK implementation.
  3. Enable debug logging: Reproducing your issue with loglevel set to debug can help you (or us) pinpoint problems.

     Don’t use debug mode in your production app

    Debug mode is great for helping you find problems as you integrate with, but we strongly recommend that you set loglevel to error in your publicly available, production app.

  4. Try our test image: Using an image that we know works in push and in-app notifications can help you narrow down problems relating to images in your messages.

If you need to contact support

We’re here to help! If you contact us for help with an SDK-related issue, we’ll generally ask for the following information. Having it ready for us can help us solve your problem faster.

  1. Share information about your device and environment: Let us know where you had an issue—the SDK and version of the SDK that you’re using, the specific device, operating system, message, use case, and so on. The more information you share with us, the easier it is for us to weed out externalities and find a solution.
  2. Share your push or in-app payload: Knowing what images you used, the shape of your payload, and so on helps us reproduce the issue and figure out exactly what went wrong.
  3. Grant access to your workspace: It may help us to see exactly what triggers a campaign, what data is associated with devices you’re troubleshooting, etc. You can grant access for a limited time, and revoke access at any time.

Examine source and destination calls in Data Pipelines

In Data Pipelines, we’ll show you both the calls that come in from your SDK and how we interpret those calls for each destination—including your workspace.

If you have a problem, you may want to go to Data Pipelines and check:

  1. That your iOS source is connected to your Journeys workspace. If you don’t connect your source to Journeys, you won’t be able to send messages, etc.
  2. Your source'sA source is a website or server that you want to capture data from—it’s a source of data! Data In tab to make sure that your app sends the right data.
  3. Your destination'sA destination is a place that you want to send data from one or more sources to. You can use your own workspace as a destination; send data to another service; or send data to your data warehouse. Data Out tab to make sure that we’re sending the right data from your SDK to the destination. This includes, where your app is a data source and your workspace is the destination!

Check out our Data Pipelines troubleshooting page for more help pinpointing issues in your integration.

Capture logs

  1. Enable debug logging in your app: Everywhere you call CustomerIO.initialize(), enable the debug log level. This includes in the Notification Service Extension that you setup for rich push.

     You should not use debug mode in your production app. Remember to disable debug logging before you release your app to the App Store.

    // During SDK initialization, enable debug logs: 
    withConfig: SDKConfigBuilder(cdpApiKey: "YOUR_CDP_API_KEY")
  2. Open the Console app (already installed in MacOS). This is a built-in application you can use to view logs produced by the SDK. We recommend that you use Console instead of Xcode to view and capture logs from the SDK because Xcode may not show you all of the logs the SDK generates.

    Console app after opening
    Console app after opening
  3. In Console, click Action > Include Info messages and Action > Include Debug messages. These settings ensure that you’ll see log messages from the SDK.

  4. In Console, on the left, select the iOS device that runs your app with the SDK. If you don’t see your device listed, plug in your iOS device into your Mac. Try to use a direct connection via the Apple cable; using a USB hub might prevent the device from showing up.

    Then, click Start streaming. You will see hundreds or even thousands of logs printed to you. Most of these log messages are not relevant. In the next steps, we’ll filter your log to find relevant messages.

  5. In the top right search bar, type “CIO” and press Enter.

    Console app after typing CIO
    Console app after typing CIO
  6. Click the dropdown and select Category. You will now only see messages sent from the SDK.

    Console app after selecting category
    Console app after selecting category
  7. In the top right, click Save to save this filter. The next time you open Console, just click that saved filter along the top of the screen to see SDK logs.

    Console app after saving filter
    Console app after saving filter
  8. Click any of the log entries on the screen (or Edit > Select All), CMD + C, then CMD + P into a text editor on your computer. Save the file as a .txt.

  9. Send the file you just saved to our support team at In your message, describe your problem and provide relevant information about:

    • The version of the SDK you’re using.
    • The type of problem you’ve encountered.
    • An existing GitHub issue URL or existing support email so we know what these log files are in reference to.

Push notification issues

Problems with rich push notifications (images, delivered metrics, etc)

If you have trouble with rich push features, like images not showing up in your push notifications, delivery metrics not being reported when a push notification is visible on the device, and so on, it’s possible that you either need to re-create your NSE target to support rich notifications your you may not have embeded the NotificationServiceExtension (NSE) at all.

  1. Remove your current NSE extension.

    1. In XCode, select your project.
    2. Go to the Signing & Capabilities tab.
    3. Click the NotificationServiceExtension target; it has a bell icon next to it.
    4. Click the minus sign to remove the target
    5. Confirm the Delete operation.
      an image illustrating the 5 clicks you'll perform to delete your NSE target.
      an image illustrating the 5 clicks you'll perform to delete your NSE target.
  2. Remove existing NSE files.

    1. Right click the NotificationServiceExtension folder in your project and select Delete.
    2. Confirm Move to Trash.
      an image illustrating the steps you'll take to delete NSE files.
      an image illustrating the steps you'll take to delete NSE files.
  3. Recreate the notification service extension, following instructions for your framework. When You create your target NSE file, make sure you select your app’s name from the Embed in Application dropdown.


  4. Then add the required files:

  5. After all files are added, go to the NSE target and, under the General tab, check Deployment Target and set it to a value that is identical to your host app’s iOS version.


When you create a new target, by default, XCode sets the highest version of deployment target version available. While testing if your device’s iOS version is lower than this deployment target, then the NSE won’t be connected to the main target and you won’t receive rich push notifications.

Then you can build and run your app to test if you can receive a rich push notification.

Why aren’t devices added to people in Production builds?

If you see devices register successfully on your Staging builds, but not in Production or TestFlight builds, there might be an issue with your project setup. Check that the Push capability is enabled for both Release and Debug modes in your project. You might also need to enable the Background Modes (Remote Notifications) capability, depending on your project setup and messaging needs.

Image display issues

If you’re having trouble, try using our test image in a message! If it works, then there’s likely a problem with your original image.

a test image of a bird that we know will work with all push notifications
a test image of a bird that we know will work with all push notifications

Android and iOS devices support different image sizes and formats. In general, you should stick to the smallest size (under 1 MB—the limit for Android devices) and common formats (PNG, JPEG).

iOSAndroidIn-App (all platforms)
Maximum size10 MB*1 MB
Maximum resolution2048 x 1024 px1038 x 1038 px
*For linked media only. If you host images in our Asset Library, you’re limited to 3MB per image.

Why didn’t everybody in my segment get a push notification?

If your segmentA group of people who match a series of conditions. People enter and exit the segment automatically when they match or stop matching conditions. doesn’t specify people who have an existing device, it’s likely that people entered your segment without using your app. If you send a push notification to such a segment, the “Sent” count will probably show fewer sends than there were people in your segment.

Why are messages sent but not delivered or opened?

The sent status means that we sent a message to your delivery provider—APNS or FCM. It’ll be marked delivered or opened when the delivery provider forwards the message to the device and the SDK reports the metric back to If a person turned their device off or put it in airplane mode, they won’t receive your push notification until they’re back on a network.

 Make sure you’ve configured your app to track metrics

If your app isn’t set up to capture push metrics, your app will never report delivered or opened metrics!

Why don’t my messages play sounds?

When you send a push notification to iOS devices that uses our SDK, you can opt to send the Default system sound or no sound at all. If your audience’s phone is set to vibrate, or they’ve disabled sound permissions for your app, the Default setting will cause the device to vibrate rather than playing a sound.

In most cases, you should use the Default sound setting to make sure your audience hears (or feels) your message. But, before you send sound, you should understand:

  1. Your app needs permission from your users to play sounds. This is done by your app, not our SDKs. Here’s an example from our iOS sample app showing how to request sound permissions.
  2. iOS users can go into System Settings and disable sound permissions for your app. Enabling the Default setting doesn’t guarantee that your audience hears a sound when your message is delivered!

 We don’t support custom sounds yet

If you want to send a custom sound, you’ll need to handle it on your own, outside the SDK and use a custom payload when you set up your push notifications.

It sounds like you want to use universal links—links that go to your app if a person has your app installed and to your website if they don’t. Universal links are a bit different than your average deep link and require a little bit of additional setup.

You can learn more about setting up universal links here. You can easily test universal links using your Notes app. Try adding a link to a note and tap it. If it drives you to your app, then you’ve set things up correctly!

If your links are opening Safari instead of your app, check this Apple document to troubleshoot.

If you click on a push notification sent by that contains a Universal Link deep link > click on the push notification > app opens for a moment > then the browser opens the URL, this could be a sign that something is wrong with your app’s Universal Link handling.

The SDK sends a request to your app’s app to give your app an opportunity to handle the Universal Link. If your app does not handle the Universal Link, the SDK will open the link in the browser instead. Let’s walk through some troubleshooting steps to try and fix this behavior so the browser does not open.

In our deep links Universal Links guide, we show a function that is required to be added to your app: application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool. Add a print("Universal Links handle code called.") statement or Xcode breakpoint to verify that your code in this function does get called.

If you click on a push notification and you do not see this print statement or breakpoint hit, verify that the deep link URL is a valid https URL and you have followed all of the Apple documentation linked in our Universal Links guide.

If you do see your print statement or breakpoint hit, then your Universal Link URL is valid and is correctly attached to the push notification for the SDK to understand. Next, verify that your app returns true from the application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool function. If your app returns false, the SDK will open the Universal Link in the browser instead of the app.

Lastly, check if there is another SDK interfering with the SDK. In some cases, customers have reported instances where Universal Links, despite being correctly configured within your app, may unexpectedly open in a web browser. This can occur due to interactions with third-party SDKs that perform method swizzling inside your app. To address this, consider reviewing the documentation of other SDKs integrated into your app and disabling swizzling as needed.

In-App message issues

My in-app messages are sent but not delivered

People won’t get your message until they open your app. If you use page rules, they won’t see your message until they visit the right screen(s), so delivery times for in-app messages can vary significantly from other types of messages.

If someone’s opened your app to the right screen and hasn’t seen your message, you should make sure that that your app and message use the same identifier. If your app identifies people by email but your message expects an ID, your message won’t be delivered!

the to field needs to match your identify call
the to field needs to match your identify call
Copied to clipboard!
Current release
Is this page helpful?
Chat with AI