---
title: "HealthKit errorAuthorizationNotDetermined: You Called Before You Asked"
canonical: "https://aifitnessapi.com/fix/healthkit-authorization-not-determined"
cluster: "Troubleshooting"
primary_query: "healthkit errorauthorizationnotdetermined"
last_reviewed: "2026-09-04"
description: "Not determined means nobody has been asked yet, not that the user said no. The ordering rule Apple documents, and the entry points that keep breaking it."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"HealthKit errorAuthorizationNotDetermined: You Called Before You Asked\", AIFitnessAPI, https://aifitnessapi.com/fix/healthkit-authorization-not-determined"
---

# HealthKit errorAuthorizationNotDetermined: You Called Before You Asked

> Apple's documentation states that errorAuthorizationNotDetermined means the app has not yet asked the user for the authorization required to complete the task, and that it occurs when your app does not request proper authorization before calling any other HealthKit method. It is not a refusal: nobody has been asked. That distinguishes it from a denied write, which Apple describes as the user not having given the app permission to save data. The fix is ordering, and the usual cause is coverage — a widget, extension, background wake-up, watch app, or newly added type that reaches the store without passing through the request you wrote for your onboarding flow.

- Canonical: https://aifitnessapi.com/fix/healthkit-authorization-not-determined
- Last reviewed: 2026-09-04
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "HealthKit errorAuthorizationNotDetermined: You Called Before You Asked", AIFitnessAPI, https://aifitnessapi.com/fix/healthkit-authorization-not-determined

---

`errorAuthorizationNotDetermined` is the one HealthKit error that is unambiguously your fault, and that is good news: it is also the one you can fix outright. It does not mean the user said no. It means nobody has been asked yet, and your code went ahead anyway.

## What Apple documents

Apple's documentation states the abstract as: "The app hasn't yet asked the user for the authorization required to complete the task." The discussion names the cause directly:

> This error occurs when your app doesn't request proper authorization before calling any other HealthKit methods. For more information on setting up HealthKit, see HealthKit.

Note the phrasing "before calling any other HealthKit methods" — the same ordering instruction Apple attaches to the device-capability cases. HealthKit's setup contract is sequential, and this error is what the framework returns when you break the sequence.

Compare the abstract with the neighbouring case. Apple describes `errorAuthorizationDenied` as "the user hasn't given the app permission to save data", and its discussion states that the error "occurs only when your app attempts to save data". The two cases sit at different points of the same state machine, and conflating them produces the two worst UX outcomes in this whole area: nagging someone who already decided, and silently giving up on someone who was never asked.

## The state machine, stated plainly

| State | How you got here | The right move |
| --- | --- | --- |
| Never asked | Your code called before requesting | Request authorization |
| Asked, user allowed the write | The sheet was shown and accepted | Proceed |
| Asked, user refused the write | The sheet was shown and refused | Stop saving; route to system settings |
| Asked, read outcome unknown | Always, for reads | Query and handle whatever comes back |

The last row is the asymmetry that makes HealthKit unlike every OAuth-shaped permission model your team has built before: the read side never reports its outcome. That is deliberate, and the reasoning plus the one exception are set out in [HealthKit authorization denied](/fix/healthkit-authorization-denied). The consequence for this page is narrow but important — "not determined" is a statement about *your request*, not about the user's answer.

## Why perfectly correct code still hits it

Nobody writes a query before a request on purpose. It happens because a modern app has several front doors, and only one of them runs your onboarding.

- **A widget or complication reload** wakes an extension that never saw your first-run flow.
- **A background delivery wake-up** runs your sync path in a process that started from nothing; if the wake-up path calls the store before the request, this is the error you get. The wiring is covered in [HealthKit background delivery not working](/fix/healthkit-background-delivery-not-working).
- **A watch app launched from the wrist** is its own process with its own lifecycle, described in [HealthKit on Apple Watch](/watch-apps/healthkit-on-apple-watch).
- **A deep link into a detail screen** skips the onboarding stack the user would otherwise have walked through.
- **A newly added type.** This is the subtle one: authorization is per type, so shipping a feature that reads a type you never included in the original request puts that type — and only that type — back in the never-asked state for every existing install.
- **A race at launch.** A request in flight while a query fires from a different task is, from HealthKit's point of view, a query before a request.

## Diagnosis order

1. **Log which type failed.** If a subset of types fails and the rest work, you are almost certainly in the newly-added-type case, and the fix is to include it in your request set rather than to touch anything else.
2. **Log which process failed.** Main app, extension, watch app, background wake-up. If it is never the main app, your request lives in the wrong place.
3. **Check the ordering, not the outcome.** The question is whether a request completed before the call, not whether it was granted. A request that was fired but not awaited has not completed.
4. **Do not re-prompt as a workaround.** Our [authorization denied](/fix/healthkit-authorization-denied) guide records Apple's documented behaviour that if the user has already decided every requested type, the request returns without prompting. A "grant access" button that re-requests will do nothing visible and leave the user stuck.
5. **Separate this from empty results.** If your query *runs* and returns nothing, you are not in this case at all; that is the ambiguity handled in [HealthKit returning no data](/fix/healthkit-no-data), and the distinct conditions that all look like nothing are enumerated in [what "no data" actually means](/blog/no-data-means-four-things). The explicit, computed version of emptiness has its own case in [errorNoData](/fix/healthkit-error-no-data).

## Fixing it, as practice

- **Put the request behind one gate.** Every path that touches the store — app, widget, watch, background task — goes through a single accessor that guarantees a completed request first. Repeating the request logic per entry point guarantees one gets forgotten.
- **Request the full set once, not type by type.** Declaring everything the feature needs up front avoids a second sheet later and keeps the never-asked state from reappearing per feature.
- **Treat a type addition as a migration.** When you add a type in a release, existing users need a fresh request for it. Plan the moment you will ask, rather than discovering it in crash-free-but-empty telemetry.
- **Await the request before the first call.** In background paths especially, make the ordering structural rather than incidental.
- **Never assume the request means yes.** A completed request moves you out of not-determined; it says nothing about what the user chose on the read side.
- **Never gate reads on an authorization check.** Run the query, render what comes back, and accept empty as a legitimate answer.

## Symptom to action

| What you observe | Case | Fix |
| --- | --- | --- |
| Save fails, you never requested | `errorAuthorizationNotDetermined` | Request first, then save |
| Save fails after the sheet | `errorAuthorizationDenied` | Route the user to system settings |
| One new type fails, others work | Not requested for that type | Add it to the request set |
| Only the extension fails | Request missing on that path | Gate every entry point |
| Query returns empty, no error | Not this case | Isolate with a write-then-read test |

## Where to go next

Apple's wording for every case in the enum is collected in the [HealthKit error reference](/healthkit-errors); the types you can put in a request set are listed in the [HealthKit identifier reference](/healthkit-identifiers); and if the types you need are clinical records, the request is a different class of authorization with an all-or-nothing failure, covered in [required authorization denied](/fix/healthkit-required-authorization-denied). The setup around all of it is in the [HealthKit integration guide](/integrate/healthkit).

## FAQ

### Does not determined mean the user denied my app?

No. Apple's abstract states the app has not yet asked the user for the authorization required to complete the task. Nobody has made a decision. A refused write is a different case, which Apple describes as the user not having given permission to save data, and its discussion notes it occurs only when your app attempts to save.

[Permalink](https://aifitnessapi.com/fix/healthkit-authorization-not-determined#faq-1)

### Why does this happen when my onboarding already requests authorization?

Because your onboarding is not the only way into HealthKit code. Widgets, extensions, background delivery wake-ups, a watch app launched from the wrist, and deep links can all make the first call in a process. Authorization is also per type, so a feature that reads a type missing from your original request set is back in the never-asked state.

[Permalink](https://aifitnessapi.com/fix/healthkit-authorization-not-determined#faq-2)

### Can I just request authorization again to clear it?

Requesting is exactly right when the state really is not determined. It is the wrong reflex once decisions have been made: Apple documents that if the user has already chosen for all the specified types, HealthKit returns the request without prompting. A grant access button that re-requests then does nothing visible and leaves the user stuck.

[Permalink](https://aifitnessapi.com/fix/healthkit-authorization-not-determined#faq-3)
