You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cloud Anchors: keyless authorization silently fails (mode auto-disabled, no error) despite a fully-configured OAuth client — while token-auth works in the same project #1777
On Android, ARCore keyless authorization for Cloud Anchors never authorizes. Config.CloudAnchorMode is committed as ENABLED at session creation, but ARCore silently downgrades it to DISABLED within ~1–2 seconds of the session starting (a native AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED begins emitting immediately), and any subsequent host throws CloudAnchorsNotConfiguredException. There is no error in logcat — it fails closed silently.
Note this is distinct from the classic host-time ERROR_NOT_AUTHORIZED: because the mode is disabled before any host, hostCloudAnchorAsync(...) throws CloudAnchorsNotConfiguredExceptionsynchronously — the async host callback with ERROR_NOT_AUTHORIZED never fires. This points at keyless token acquisition failing at session-configure time, not at host time.
Server-side ARCore API metrics confirm the failure is upstream of the API: not a single request reaches arcore.googleapis.com under an OAuth-client credential. The keyless token is never successfully obtained on-device, so CloudAnchorService.CreateAnchor is never called.
Critically, every documented keyless prerequisite is verified present, and iOS token-auth Cloud Anchors work in the exact same GCP project — so the project, API, billing, and anchor service are all healthy. Only Android keyless is affected.
This is the same AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED-despite-ENABLED symptom reported on this SDK before and never resolved (#1173, #1250), which we believe is the silent surfacing of the long-standing keyless ERROR_NOT_AUTHORIZED failure (#80, #58) — pinned here to a fully-verified configuration.
App minify/ProGuard: disabled (isMinifyEnabled = false) — the documented keep-rules are therefore not applicable
Expected behavior
With a valid OAuth 2.0 Android client ID (package + SHA-1) in the project that has the ARCore API enabled, keyless authorization should succeed and CloudAnchorMode.ENABLED should stay enabled, allowing hostCloudAnchorAsync / resolveCloudAnchorAsync.
Actual behavior
sessionConfiguration sets config.cloudAnchorMode = Config.CloudAnchorMode.ENABLED. Reading session.config.cloudAnchorMode back immediately after onSessionCreated confirms it is committed ENABLED.
Within ~1–2 s of the session starting, ARCore begins emitting the native error below, and session.config.cloudAnchorMode now reads DISABLED (verified by reading it again just before the host attempt).
hostCloudAnchorAsync(anchor, 365, …) throws CloudAnchorsNotConfiguredException (synchronously, from nativeHostCloudAnchorAsync); the piece falls back to GPS-only.
No authorization error is logged (logcat filtered for arcore|cloud.?anchor|NOT_AUTHORIZED|auth.?token|oauth|GoogleAuth|permission|token shows nothing beyond the mode-downgrade error below — including nothing from the com.google.android.gms process).
No request reaches arcore.googleapis.com under an OAuth-client credential (server metrics show zero — see below).
The only native output is the silent downgrade itself, repeating from ~1–2 s after session start:
E native: ################ ARCore Native Error ##################
E native: ARCoreError: third_party/arcore/ar/persistence/cloud_anchor_manager.cc:288
E native: ARCoreError: third_party/arcore/ar/core/session.cc:4287
E native: Anchor Hosting is not configured. [type.googleapis.com/util.ErrorSpacePayload=
'ArStatusErrorSpace::AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED']
...
I native: cloud_anchor_manager.cc:530] Anchor Hosting is not configured. (repeats ~1×/s)
No line names the token/OAuth denial — the failure is entirely inside Google Play services and is not surfaced to the app or logcat.
Configuration verified present (nothing missing per the docs)
Requirement
Status
ARCore API (arcore.googleapis.com) enabled in the project
✅ ENABLED
Billing enabled on the project
✅
play-services-auth 16+
✅ 21.1.1
OAuth 2.0 Android client ID for the exact (package, SHA-1), in the same project as the ARCore API
✅ exists (<CLIENT_ID>.apps.googleusercontent.com, type ANDROID, package com.korrelated.kanvio.dev, cert 75:81:4F:83:86:8A:E0:11:4F:D6:53:22:2C:06:CC:77:59:86:80:D5)
Installed APK signing cert == that SHA-1 (apksigner verify --print-certs)
✅ verified equal
OAuth consent screen not blocking
✅ tried Internal, External + Testing (account added as test user), and External + In production — no change in any mode
ProGuard/R8 keep-rules
N/A (minify disabled)
What we ruled out
Account / consent-screen gating — failure is identical across Internal, External+Testing, and External+In-production, so keyless authorization is not being gated by the OAuth consent screen or the device Google account.
Signing-key mismatch — verified against the actually-installed APK, not just the local build: pulled it (adb shell pm path → adb pull) and ran apksigner verify --print-certs, which reports certificate SHA-1 75:81:4F:83:86:8A:E0:11:4F:D6:53:22:2C:06:CC:77:59:86:80:D5 (SHA-256 f0290eb8dc7709c90f6b10ed89b118e60af7200c793b89de28aa491404ada682) — matching the OAuth client's registered SHA-1 exactly. Rules out a build/CI signing with a different debug key.
Project/API/billing — all enabled; and iOS token-auth (below) succeeds against the same project.
OAuth-client type ("dedicated" vs Firebase-auto-created) — attempting to create a separate dedicated OAuth Android client for the same (package, SHA-1) is rejected: "The Android package name and fingerprint are already in use." (Google tracking number c2962162132488701.) So the existing client is the single canonical client for that identity; there is no alternative client to switch to.
Contrast: token-auth works in the same project (proves the backend is healthy)
The iOS build of the same app authenticates via token auth — GARSession.setAuthToken(<JWT>) with a JWT signed by a project service account, aud: https://arcore.googleapis.com/. Two independent proofs the backend is healthy:
In this bug's project (same project): iOS token-auth CloudAnchorService.CreateAnchor returns 200 — so the ARCore API, billing, and Cloud Anchor authorization all function in the very project where Android keyless fails. Android keyless, by contrast, produces zero requests to the API. (The read RPC GetAnchor is not exercised by the keyless failure and is irrelevant to it — the Android failure occurs before any request is sent, so GetAnchor's status either way has no bearing on this bug.)
In our production project (same app, same architecture): the full host→resolve round-trip works end-to-end — CreateAnchor 200 and GetAnchor 200, with Cloud Anchors persisted as recently as this week.
So the ARCore Cloud Anchor service, API enablement, and billing are all functioning — the failure is specific to the Android keyless authorization path never obtaining a token.
Project with arcore.googleapis.com enabled, billing on, and an OAuth 2.0 Android client for the app's package + signing SHA-1 (here, auto-created by Firebase from the Android app's registered SHA-1).
Observe: mode downgrades ENABLED → DISABLED within ~1–2 s of session start (AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED begins emitting); hostCloudAnchorAsync throws CloudAnchorsNotConfiguredException; no logcat error; no request reaches the ARCore API.
Ask
Is there an additional, undocumented requirement for Android keyless authorization when the OAuth Android client was auto-created by Firebase (from the Firebase Android app's SHA registration) rather than hand-created — given that a hand-created one for the same (package, SHA-1) is rejected as a duplicate?
Can you surface the actual token-acquisition failure to logcat? Today it fails silently, which makes keyless ERROR_NOT_AUTHORIZED-class problems nearly undiagnosable from the client.
References (all open & unresolved)
Same AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED symptom — mode ENABLED yet host/resolve reports "not configured" — reported on this SDK before and never resolved (both thinner than this report; neither identifies the keyless-auth cause):
google-ar/arcore-android-sdk Cloud anchors not configured #1173 — "Cloud anchors not configured" (resolveCloudAnchor() throws despite getCloudAnchorMode() == ENABLED)
Summary
On Android, ARCore keyless authorization for Cloud Anchors never authorizes.
Config.CloudAnchorModeis committed asENABLEDat session creation, but ARCore silently downgrades it toDISABLEDwithin ~1–2 seconds of the session starting (a nativeAR_ERROR_CLOUD_ANCHORS_NOT_CONFIGUREDbegins emitting immediately), and any subsequent host throwsCloudAnchorsNotConfiguredException. There is no error in logcat — it fails closed silently.Note this is distinct from the classic host-time
ERROR_NOT_AUTHORIZED: because the mode is disabled before any host,hostCloudAnchorAsync(...)throwsCloudAnchorsNotConfiguredExceptionsynchronously — the async host callback withERROR_NOT_AUTHORIZEDnever fires. This points at keyless token acquisition failing at session-configure time, not at host time.Server-side ARCore API metrics confirm the failure is upstream of the API: not a single request reaches
arcore.googleapis.comunder an OAuth-client credential. The keyless token is never successfully obtained on-device, soCloudAnchorService.CreateAnchoris never called.Critically, every documented keyless prerequisite is verified present, and iOS token-auth Cloud Anchors work in the exact same GCP project — so the project, API, billing, and anchor service are all healthy. Only Android keyless is affected.
This is the same
AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGURED-despite-ENABLEDsymptom reported on this SDK before and never resolved (#1173, #1250), which we believe is the silent surfacing of the long-standing keylessERROR_NOT_AUTHORIZEDfailure (#80, #58) — pinned here to a fully-verified configuration.Environment
com.google.ar:core:1.54.0(via SceneViewio.github.sceneview:arsceneview)hostCloudAnchorAsync(anchor, 365, …)) → keyless is mandatory (API key caps at 24h)com.google.android.gms:play-services-auth:21.1.1(transitive viaandroidx.credentials:credentials-play-services-auth)SM-S731U, Android 16 / One UI 8.0 (build fingerprintsamsung/r13ssqw/r13s:16); Google Play Services for AR (ARCore)1.54.260890093(versionCode260890093) — the same build reported in FatalException from Session.resume() on Samsung SM-X520 (Galaxy Tab S10 FE) / One UI 8.0 — regression after Play Services for AR auto-update to 1.54.x #1762com.korrelated.kanvio.devisMinifyEnabled = false) — the documented keep-rules are therefore not applicableExpected behavior
With a valid OAuth 2.0 Android client ID (package + SHA-1) in the project that has the ARCore API enabled, keyless authorization should succeed and
CloudAnchorMode.ENABLEDshould stay enabled, allowinghostCloudAnchorAsync/resolveCloudAnchorAsync.Actual behavior
sessionConfigurationsetsconfig.cloudAnchorMode = Config.CloudAnchorMode.ENABLED. Readingsession.config.cloudAnchorModeback immediately afteronSessionCreatedconfirms it is committedENABLED.session.config.cloudAnchorModenow readsDISABLED(verified by reading it again just before the host attempt).hostCloudAnchorAsync(anchor, 365, …)throwsCloudAnchorsNotConfiguredException(synchronously, fromnativeHostCloudAnchorAsync); the piece falls back to GPS-only.arcore|cloud.?anchor|NOT_AUTHORIZED|auth.?token|oauth|GoogleAuth|permission|tokenshows nothing beyond the mode-downgrade error below — including nothing from thecom.google.android.gmsprocess).arcore.googleapis.comunder an OAuth-client credential (server metrics show zero — see below).The only native output is the silent downgrade itself, repeating from ~1–2 s after session start:
No line names the token/OAuth denial — the failure is entirely inside Google Play services and is not surfaced to the app or logcat.
Configuration verified present (nothing missing per the docs)
arcore.googleapis.com) enabled in the projectplay-services-auth16+(package, SHA-1), in the same project as the ARCore API<CLIENT_ID>.apps.googleusercontent.com, type ANDROID, packagecom.korrelated.kanvio.dev, cert75:81:4F:83:86:8A:E0:11:4F:D6:53:22:2C:06:CC:77:59:86:80:D5)apksigner verify --print-certs)What we ruled out
adb shell pm path→adb pull) and ranapksigner verify --print-certs, which reports certificate SHA-175:81:4F:83:86:8A:E0:11:4F:D6:53:22:2C:06:CC:77:59:86:80:D5(SHA-256f0290eb8dc7709c90f6b10ed89b118e60af7200c793b89de28aa491404ada682) — matching the OAuth client's registered SHA-1 exactly. Rules out a build/CI signing with a different debug key.(package, SHA-1)is rejected: "The Android package name and fingerprint are already in use." (Google tracking numberc2962162132488701.) So the existing client is the single canonical client for that identity; there is no alternative client to switch to.Contrast: token-auth works in the same project (proves the backend is healthy)
The iOS build of the same app authenticates via token auth —
GARSession.setAuthToken(<JWT>)with a JWT signed by a project service account,aud: https://arcore.googleapis.com/. Two independent proofs the backend is healthy:CloudAnchorService.CreateAnchorreturns200— so the ARCore API, billing, and Cloud Anchor authorization all function in the very project where Android keyless fails. Android keyless, by contrast, produces zero requests to the API. (The read RPCGetAnchoris not exercised by the keyless failure and is irrelevant to it — the Android failure occurs before any request is sent, soGetAnchor's status either way has no bearing on this bug.)CreateAnchor 200andGetAnchor 200, with Cloud Anchors persisted as recently as this week.So the ARCore Cloud Anchor service, API enablement, and billing are all functioning — the failure is specific to the Android keyless authorization path never obtaining a token.
Reproduction
com.google.ar:core:1.54.0, Cloud Anchor modeENABLED, persistent host TTL 365.arcore.googleapis.comenabled, billing on, and an OAuth 2.0 Android client for the app's package + signing SHA-1 (here, auto-created by Firebase from the Android app's registered SHA-1).play-services-authpresent; consent screen published.ENABLED → DISABLEDwithin ~1–2 s of session start (AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGUREDbegins emitting);hostCloudAnchorAsyncthrowsCloudAnchorsNotConfiguredException; no logcat error; no request reaches the ARCore API.Ask
(package, SHA-1)is rejected as a duplicate?ERROR_NOT_AUTHORIZED-class problems nearly undiagnosable from the client.References (all open & unresolved)
Same
AR_ERROR_CLOUD_ANCHORS_NOT_CONFIGUREDsymptom — modeENABLEDyet host/resolve reports "not configured" — reported on this SDK before and never resolved (both thinner than this report; neither identifies the keyless-auth cause):resolveCloudAnchor()throws despitegetCloudAnchorMode() == ENABLED)Keyless-authorization
ErrorNotAuthorized, open & unresolved (the likely underlying failure this report exposes as a silent mode-downgrade):