Skip to content
Agencei
Urgency : high

Application crashes: find the cause of the crash and fix it for good

A crashing application closes abruptly, freezes or restarts in a loop. On mobile, the user sees the app disappear or a message saying the app has stopped; on a web application or backend, it shows as 500 errors, timeouts or a service restarting endlessly in Docker, Kubernetes or PM2.

Causes fall into a few families: unhandled exceptions, exhausted memory, incompatible dependencies or libraries after an update, behaviour changes in an operating system (iOS, Android), unexpected data, and overload. Each leaves usable traces in crash logs, server logs or an error tracking tool.

This page explains where to find those traces depending on the type of application, how to reproduce the crash, what the most frequent causes are and how to fix them so the problem does not return in the next release.

Typical symptoms

  • The mobile app closes at launch or on a specific action, sometimes only on certain devices or OS versions.
  • Crashes started after an update of the app, iOS, Android or a library.
  • The web application shows a blank page, a 500 error or stays stuck on an endless loading state.
  • The backend restarts in a loop (CrashLoopBackOff in Kubernetes, rising PM2 or Docker restarts), or goes down under load.
  • Memory usage grows steadily until the crash (memory leak).
  • Firebase Crashlytics, Sentry, App Store Connect or the Google Play Console report a rising crash rate.

Possible causes

Unhandled exception

Unexpected null value, array index out of bounds, API response in a different format than expected, division by zero: the error bubbles up to the main process and kills it.

Memory exhaustion

Images loaded at full resolution, list views not recycled, unbounded caches, leaks in subscriptions or event listeners. On mobile, the system kills the app; on the server, it is the OOM killer or a Node or Java "heap out of memory" error.

Incompatible dependencies

Library updated with a breaking change, native versions (CocoaPods, Gradle) not aligned with React Native or Flutter, partial package update.

Operating system update

New iOS or Android version that restricts a permission, changes an API or a behaviour (background, notifications, storage), or a new Node, Java or Python version on the server side.

Unexpected data or state

A malformed record, a corrupted local cache, a user with a rare configuration: the crash only happens for some accounts and is hard to reproduce.

Overload or failing external resource

Traffic spike, third-party service that stops responding with no timeout configured, saturated database: requests pile up until resources run out.

Configuration or deployment error

Missing environment variable, expired API key, configuration file absent from the Docker image, database migration not run.

Checks to perform

  1. 1

    Retrieve mobile crash logs

    iOS: Xcode > Window > Devices and Simulators > View Device Logs, or Settings > Privacy > Analytics on the device; Console.app in real time. Android: adb logcat on a connected device, or Android Studio > Logcat, filtered on "FATAL EXCEPTION" and the package name.

  2. 2

    Check the tracking tools

    Firebase Crashlytics, Sentry, Bugsnag or App Store Connect > Crashes and Google Play Console > Android vitals group crashes by version, device and OS, with the stack trace. It is the most effective starting point.

  3. 3

    Read the server logs

    docker logs container, kubectl logs pod --previous for the container that just died, pm2 logs, journalctl -u service, or the application logs (Laravel, Symfony, Spring Boot). Look for the last trace before the restart.

  4. 4

    Check memory

    Mobile: Xcode Instruments (Allocations, Leaks) or Android Studio Profiler to watch for continuous growth. Server: docker stats, kubectl top pod, dmesg -T | grep -i oom, or APM metrics to spot a leak or a spike.

  5. 5

    Reproduce the crash

    Note the version, device, OS, account used and sequence of actions. Test on a physical device and on an emulator with the same OS version. On the server, replay the request identified in the logs.

  6. 6

    Check dependencies and configuration

    Compare installed versions with those of the last stable release (package.json, Podfile.lock, build.gradle, requirements.txt, pom.xml). Verify environment variables and secrets in the environment that crashes.

  7. 7

    Examine Kubernetes events or the orchestrator

    kubectl describe pod shows the reason for the last termination (OOMKilled, Error, liveness probe failed) and the exit code, which immediately points to memory, an exception or an overly strict health check.

Solutions

Fix the exception at the source

Handle the case that triggers the error (null value, unexpected format), validate incoming data, add error handling that informs the user without killing the app.

Solve memory problems

Resize images, recycle list views, cap caches, release subscriptions and listeners, adjust container memory limits and heap size (Node --max-old-space-size, Java -Xmx) consistently.

Align dependencies

Roll back to the previous stable version while fixing, then update in a coordinated way by reading release notes and testing on the targeted OS versions.

Adapt the app to the new OS

Update SDKs, fix permissions and deprecated APIs, test on iOS and Android beta versions before their public release.

Make the backend resilient

Timeouts and retries on external calls, rate limiting, queues for heavy tasks, appropriate health checks and autoscaling.

Deploy carefully

Staged rollout (percentage of users on the stores, canary or blue-green on the server side), crash rate monitoring after each release and the ability to roll back immediately.

When should you call a professional?

  • The crash rate is rising on a published version and you need to ship a fix quickly.
  • Crash logs mention native code, third-party libraries or traces you do not know how to interpret.
  • The crash only happens in production or on some devices and you cannot reproduce it.
  • The app was built by a provider who is no longer available and you have no error tracking in place.
  • The backend goes down under load and you are preparing for a high-traffic deadline.

How Agencei can help

  1. 1

    Trace collection

    Set-up or use of Crashlytics, Sentry or an APM, crash log retrieval, symbolication of native traces (dSYM, ProGuard mapping).

  2. 2

    Reproduction and diagnosis

    Reproduction on physical devices and test environments, analysis of the stack trace, memory and dependencies, root cause identification.

  3. 3

    Fix

    Targeted code fix, coordinated dependency update, configuration or infrastructure adjustment, regression tests.

  4. 4

    Release

    Store delivery or server deployment with rollback capability, crash rate monitoring over the first hours.

  5. 5

    Hardening

    Automated tests on critical scenarios, continuous monitoring, alerts, and recommendations to make the next releases more reliable.

Frequently asked questions

Where do I find a mobile app's crash logs?

On iOS, in Xcode (Devices and Simulators > View Device Logs), in Console.app or in App Store Connect. On Android, with adb logcat, in Android Studio (Logcat) or in Google Play Console > Android vitals. A tool such as Crashlytics or Sentry centralises all of it.

Why does the app crash only for some users?

Because of a particular combination of device, OS version, data or settings (language, permissions, battery saver). Tracking tools let you group crashes by these criteria and target the reproduction.

Do I need to republish a fixed version on the stores?

Yes for a fix in native code or bundled JavaScript. Some over-the-air update solutions (CodePush, Expo Updates) let you ship a JavaScript fix without going through store review, within the allowed limits.

What is CrashLoopBackOff?

It is the state of a Kubernetes pod whose container crashes at every start. kubectl logs --previous and kubectl describe pod show the error and the termination reason (OOMKilled, exception, failed probe).

How long does it take to fix a crash?

An exception clearly identified in the traces is often fixed within a few hours. An intermittent crash tied to memory, rare data or native code can take several days of reproduction and analysis.

Tell us about your project

Describe your need in a few lines: we come back to you with a first analysis and the next steps.