Why Is Google Health Connect Returning No Data?
Updated July 9, 2026
Your Android app calls HealthConnectClient.readRecords(...), gets no error worth acting on, and the list comes back empty. The single most common reason is not your code at all: no source app is writing that record type into Health Connect, so there is genuinely nothing to read. Health Connect is an on-device store, not a data source — something (Fitbit, Samsung Health, the phone's step recorder) has to populate it first. The quick check: open the Health Connect UI, go to App permissions / Data and access, and confirm at least one app is writing the exact type you are reading.
If a writer exists and reads are still empty, work down the ranked causes below. The other frequent culprits are a per-type read permission you never actually got granted (which can surface as a SecurityException), Health Connect not being available on the device (getSdkStatus is not SDK_AVAILABLE), and the default 30-day history window hiding older data. For the iOS equivalent of this problem, see HealthKit returns no data; to re-check your setup end to end, use the Google Health Connect integration guide.
Version note. API names below (
HealthConnectClient,getSdkStatus,getGrantedPermissions,TimeRangeFilter,PERMISSION_READ_HEALTH_DATA_HISTORY) are current stable Health Connect Jetpack API as of 2026. Play Console health-data policy specifics change often — verify those against current Google documentation before you ship.
Most likely causes (ranked)
- No source/provider app is writing that record type. Health Connect is empty until an app writes into it. Perfect code plus perfect permissions still returns nothing if no writer exists for that type.
- The per-type read permission was never granted. Permissions are granular per record type and per direction (read vs write). Reading a type you were not granted yields an empty result or a
SecurityException. - Health Connect is not available (
getSdkStatusis notSDK_AVAILABLE). If the SDK reports unavailable or "provider update required," you cannot read anything. - The default ~30-day history cap. You only see roughly the last 30 days unless you request and are granted
PERMISSION_READ_HEALTH_DATA_HISTORY. - Play Console health-data declaration gating production. Certain data types can be blocked in production builds until your health apps declaration is submitted and approved.
Step 1: Confirm an app is actually writing that record type
Before debugging code, rule out the boring answer. On the device, open Health Connect (Settings → Apps → special access, or the Health Connect app on older devices), then Data and access and browse the specific category (steps, heart rate, sleep, etc.). If no samples appear there, no reader can ever return data.
Fix: install or enable a writer for that type — for example Fitbit, Samsung Health, or the phone's built-in step recorder — and confirm data lands in the Health Connect data browser before you touch your app again. This is the same class of bug as an empty HealthKit store on iOS (HealthKit no data): the platform is a store, not a sensor.
Step 2: Verify Health Connect is available with getSdkStatus
Every Health Connect call assumes the platform is present and usable. Call HealthConnectClient.getSdkStatus(context) first and branch on the result — anything other than SDK_AVAILABLE means you cannot read.
when (HealthConnectClient.getSdkStatus(context)) {
HealthConnectClient.SDK_AVAILABLE -> {
val client = HealthConnectClient.getOrCreate(context)
// proceed with reads
}
HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED -> {
// send the user to update Health Connect
}
else -> {
// SDK_UNAVAILABLE — Health Connect not usable on this device
}
}
If you skip this check you may be calling into a client that will never return data. On older devices Health Connect can be an installable app rather than a bundled system module, so treat "not available" as a real, common state and route the user to install or update it.
Step 3: Check the read permission is granted (not just declared)
Declaring a permission in the manifest is not the same as having it granted at runtime. Read the currently granted set and confirm the exact per-type read permission is present.
val granted = client.permissionController.getGrantedPermissions()
val stepsRead = HealthPermission.getReadPermission(StepsRecord::class)
if (stepsRead !in granted) {
// permission not granted — launch your permission request flow.
// Reading now would return empty or throw SecurityException.
}
If getGrantedPermissions() does not contain HealthPermission.getReadPermission(<Record>::class) for the type you are reading, request it. A SecurityException on the read is the tell that the permission is either declared-but-not-granted or not declared at all. Remember: uninstalling your app revokes all its Health Connect permissions, so a fresh install starts from zero.
Step 4: Widen the TimeRangeFilter and rule out the 30-day history cap
If recent data appears but older data is empty (or errors), you are hitting the history window. By default an app can read data from up to ~30 days before any permission was first granted. On Android 14+ there is no historical limit reading your own app's data, but a 30-day limit reading other apps' data; on Android 13 and lower the 30-day limit applies to reading any data.
First widen the filter to prove the query itself is not the problem:
val response = client.readRecords(
ReadRecordsRequest(
recordType = StepsRecord::class,
timeRangeFilter = TimeRangeFilter.between(
Instant.now().minus(365, ChronoUnit.DAYS), // wide window: does ANY data appear?
Instant.now()
)
)
)
If seven days returns data but ninety days does not, that is the history cap, not a bug. To read records older than ~30 days, declare and request PERMISSION_READ_HEALTH_DATA_HISTORY; without it, an attempt to read records older than 30 days results in an error. Note the window resets from the reinstall date if the user reinstalls your app.
Step 5: Confirm the Play Console health-data declaration for production
Sideloaded and debug builds behave differently from Play-distributed ones. Apps that request Health Connect data types must complete the Play Console health apps declaration and pass review, and production access to certain data types can be gated until that is approved.
Confirm the declaration is submitted and approved for the release track you are testing. If a type reads fine in a local/dev build but returns nothing from a production install, suspect this gating rather than your code. (As of 2026, verify the exact policy and gated-type list against current Play Console documentation — these change.)
Still stuck? Diagnostic checklist
Run these in order — each rules out one ranked cause:
- Is anything writing the type? Health Connect UI → Data and access → the specific category shows samples. If empty, install a writer (Step 1).
- Is Health Connect available?
getSdkStatus(context)returnsSDK_AVAILABLE(Step 2). - Is the read permission granted?
getGrantedPermissions()containsHealthPermission.getReadPermission(<Record>::class); noSecurityExceptionon read (Step 3). - Is it just old data? A short
TimeRangeFilterreturns data but a long one does not → grantPERMISSION_READ_HEALTH_DATA_HISTORY(Step 4). - Is production gated? The type works in a dev build but not a Play install → check the health apps declaration (Step 5).
If all five pass and reads are still empty, capture the exact record type, the TimeRangeFilter bounds, the granted-permission set, and any SecurityException stack trace before escalating. For a clean-slate re-check of the whole flow, walk back through the Google Health Connect integration guide; if you also ship on iOS, the HealthKit no-data guide covers the Apple-side equivalents.
Frequently asked questions
- Why is Health Connect empty when my code has no errors?
- Because Health Connect is an on-device store, not a data source. If no app has written the record type you are reading, a correct query with correct permissions still returns an empty list. Open the Health Connect UI, go to Data and access, and confirm at least one app is writing that exact type before you keep debugging your code.
- What causes a SecurityException when reading from Health Connect?
- A SecurityException on a read almost always means the per-type read permission is either declared in the manifest but not granted at runtime, or not declared at all. Call getGrantedPermissions and confirm it contains HealthPermission.getReadPermission for the record class you are reading, then run your permission request flow. Note that uninstalling your app revokes all its Health Connect permissions.
- Why can I only read the last 30 days of data?
- By default an app can read Health Connect data from up to about 30 days before any permission was first granted. On Android 14 and later there is no limit reading your own app's data but a 30-day limit reading other apps' data; on Android 13 and lower the limit applies to any data. To read older records, declare and request PERMISSION_READ_HEALTH_DATA_HISTORY, otherwise reads older than 30 days error out.
- What does getSdkStatus tell me?
- getSdkStatus reports whether Health Connect is usable on the device. SDK_AVAILABLE means you can proceed; SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED means the user must update Health Connect; and SDK_UNAVAILABLE means it is not usable on that device. On older devices Health Connect can be an installable app rather than a bundled system module, so treat unavailable as a common, real state and prompt install or update.
- Does a production build behave differently from my dev build?
- It can. Apps requesting Health Connect data types must complete the Play Console health apps declaration and pass review, and production access to certain types can be gated until that is approved. If a type reads fine in a sideloaded or debug build but returns nothing from a Play install, suspect this gating. As of 2026, verify the exact policy against current Play Console documentation, since these specifics change.
Keep reading
Independent comparison, last reviewed July 9, 2026. Pricing, rate limits, and feature availability change often — confirm current details in each provider’s official documentation before you commit. Product and company names are trademarks of their respective owners; AIFitnessAPI is not affiliated with, endorsed by, or sponsored by any product listed here.
← All troubleshooting · by AIFitnessAPI