Skip to content
AF
Troubleshooting

HealthKit Workout Session Errors: Four Cases, Two of Them Undocumented

Last verified September 4, 2026 · 5 min read

Four HKError cases end a workout session, and Apple describes only two of them. Apple's documentation states that errorAnotherWorkoutSessionStarted means another app started a session, and that Apple Watch runs one workout session at a time, so your session receives the error and then ends while the second one starts. Apple states that errorUserExitedWorkoutSession means the user exited your application while a session was running, and that workout sessions end when the app goes into the background. The remaining two, errorBackgroundWorkoutSessionNotAllowed and errorWorkoutActivityNotAllowed, are published with no abstract at all, so treat them as unknown codes rather than inferring behaviour. In every case the session is already gone, which makes continuous persistence the only real defence.

Covered here:HealthKit

A workout session ending on its own is the most disruptive failure a fitness app can ship, because the user is mid-effort and the data is mid-flight. Four HKError cases cover the ways a session can be taken away from you. Two of them Apple describes; two of them Apple names and nothing more. Knowing which is which is the difference between handling a documented lifecycle and guessing.

The four cases, and what Apple says about each#

CaseApple's abstractDocumented?
errorAnotherWorkoutSessionStarted"Another app started a workout session."Yes, with discussion
errorUserExitedWorkoutSession"The user exited your application while a workout session was running."Yes, with discussion
errorBackgroundWorkoutSessionNotAllowedNone publishedNo
errorWorkoutActivityNotAllowedNone publishedNo

The split is visible in Apple's own structure. The first two sit in the accessing-errors group with abstracts and discussion paragraphs. The other two appear as type properties carrying no abstract at all — the name is the entire published content. Apple's platform list introduces that pair at iOS 17.0 and watchOS 10.0, which is the only other fact available about them. Everything on this page about those two is inference, and marked as such.

errorAnotherWorkoutSessionStarted: you were displaced#

Apple's discussion is precise about the mechanism and the ordering:

This error occurs whenever a second workout session is started. Apple Watch only runs one workout session at a time. If the user begins a second workout session in a different app, the original session receives this error message and then ends. The second session then starts.

Three consequences follow from Apple's own sentences. One session at a time is a platform rule, not a race you can win. Your session receives the error and then ends — the error is a notification of a decision, not a request you can refuse. And the other app's session starts regardless, so the user has made a choice, even if they made it by accident.

The design conclusion, as practice: never restart automatically. Grabbing the session back would take it from whichever app the user just chose, and if that app is written the same way you get two apps fighting over the wrist. Save what you have, tell the user their session ended because another app started one, and let them decide.

errorUserExitedWorkoutSession: the app left the foreground#

Apple's abstract states the trigger — "the user exited your application while a workout session was running" — and the discussion is one sentence: "Workout sessions end when the app goes into the background."

That is all Apple publishes here, and it is worth resisting the urge to elaborate. The behaviour of background execution on the watch changes across releases and configurations, and the honest position is that this error is what you receive when the session ends this way. What the sentence tells you to design for is clear enough: session state must be durable before you need it, because the moment you find out is the moment it is over.

The two undocumented cases#

errorBackgroundWorkoutSessionNotAllowed and errorWorkoutActivityNotAllowed are published with no abstract and no discussion. Apple documents nothing about when either is returned, and this page will not pretend otherwise.

What you may legitimately take from a name is a hint about where to look, never a claim about behaviour:

CaseWhat the name suggests you inspectWhat Apple confirms
errorBackgroundWorkoutSessionNotAllowedSomething about starting or running a session from the backgroundNothing
errorWorkoutActivityNotAllowedSomething about a workout activity being rejectedNothing

Handle both the way you would handle any unnamed failure: log the raw domain and code, keep the session data you already have, surface a neutral message, and do not encode a guess into your control flow. The general procedure is on undocumented HealthKit errors.

A lifecycle that survives all four#

None of the following is Apple's documented behaviour; it is how to build so that any of these four cases costs the user as little as possible.

  • Persist continuously, not at the end. If your workout is only written when the user taps stop, every case on this page loses the session. Checkpoint the accumulating data as you go so an involuntary end becomes a shortened workout rather than a deleted one.
  • Treat every ending as terminal. All four cases end with you not owning a session. Collapse them into one recovery path, and vary only the message.
  • Never auto-restart. For the displaced case Apple's discussion makes the reason explicit; for the others, restarting a session the system just refused is a loop.
  • Tell the truth in the message. "Another app started a workout" is checkable by the user and does not blame them. A generic "something went wrong" invites the support ticket.
  • Offer to save, always. Give the user an explicit way to keep the partial session. Deciding whether a partial workout is worth keeping is their call.
  • Log the case name, not a category. Four codes into one "workout error" counter and you can never tell a displaced session from an undocumented refusal in the field.

Symptom to action#

What you observeCaseRecovery
Session ends when the user starts another app's workouterrorAnotherWorkoutSessionStartedSave, explain, do not restart
Session ends as the app leaves the foregrounderrorUserExitedWorkoutSessionSave, explain, offer to resume manually
A start or activity is refused with an undocumented caseThe two unnamed casesLog raw, fail soft, keep the data
Reads fail but the session is fineNot a session errorCheck the lock and authorization cases

Where to go next#

The structural side of this — how a watch workout app is put together, and what runs when — is in the anatomy of a watchOS workout app and Apple Watch background execution. If your session data has to reach the phone, see mirroring workouts to iPhone. The complete enum with Apple's wording and honest gaps is the HealthKit error reference, and if a read is failing rather than a session, start with HealthKit database inaccessible.

Frequently asked questions

Can two apps run a workout session at the same time?
Apple's discussion states that Apple Watch only runs one workout session at a time. If the user begins a second session in a different app, Apple says the original session receives errorAnotherWorkoutSessionStarted and then ends, and the second session then starts. Your session is not being asked to yield; it is being told that it already has.
Should my app restart the session automatically after this error?
As a practice, no. Restarting takes the session back from whichever app the user just chose, and if that app is written the same way the two will fight over the wrist. Save what you have, say plainly that another app started a workout, and let the person decide what happens next.
What do the two undocumented workout errors mean?
Apple publishes no abstract and no discussion for errorBackgroundWorkoutSessionNotAllowed or errorWorkoutActivityNotAllowed, so the honest answer is that Apple documents nothing. Their names suggest where to look in your own app, which is a hypothesis to test, not a fact about the framework. Log the raw code, keep the session data, and avoid encoding a guess.

Keep reading

Elsewhere on the site

Pages that share this one’s concepts and sources, from other sections.

Next steps

Was this page useful?

Independent comparison, last reviewed September 4, 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