---
url: 'https://www.corbado.com/tr/blog/webauthn-hatalari'
title: 'Üretim Ortamında WebAuthn Hataları: Kapsamlı Rehber (2026)'
description: 'Üretim ortamında NotAllowedError gibi yaygın WebAuthn hatalarının ne anlama geldiğini ve bunların işlem türüne, zamanlamaya ve platform bağlamına göre nasıl sınıflandırılacağını öğrenin.'
lang: 'tr'
author: 'Vincent Delitz'
date: '2026-07-03T07:10:40.550Z'
lastModified: '2026-07-03T07:10:43.507Z'
keywords: 'webauthn hataları, NotAllowedError, AbortError, SecurityError, WebAuthn sorun giderme, geçiş anahtarı hata sınıflandırması, koşullu oluşturma hataları, ASAuthorizationError, ASAuthorizationError kodları, androidx.credentials, Credential Manager geçiş anah'
category: 'WebAuthn Know-How'
---

# Üretim Ortamında WebAuthn Hataları: Kapsamlı Rehber (2026)

## 1. Giriş

Üretim ortamında WebAuthn hataları kafa karıştırıcıdır
çünkü tarayıcılar, birden fazla temel nedeni temsil edebilen küçük bir `DOMException` adları kümesi (örneğin `NotAllowedError`) sunar. Bunun da ötesinde, "hataların" büyük çoğunluğu -
genellikle optimize edilmiş
büyük ölçekli dağıtımlarda %95'in üzerindedir - aslında
**beklenen bir davranıştır** (kullanıcının işletim sistemi geçiş anahtarı (passkey) istemini iptal etmesi).

> Önemli: Tarayıcılar, gizlilik nedenleriyle, kullanıcının aktif olarak
> iptal edip etmediğini veya hiçbir geçiş anahtarının bulunup bulunmadığını ayırt etmezler. Ancak, hem web'de hem de yerel platformlarda bazı durumlarda ve yeterli
> bağlamla, bu durumların bazıları zamanlama gibi sinyaller kullanılarak
> ayırt edilebilir.

Bu adların standart tanımlarını istiyorsanız,
[MDN `DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) ile başlayın. Bu
istisnalara yol açan WebAuthn'e özgü koşullar (ve tarayıcıların zorlaması gerekenler) için
[W3C Web Authentication spesifikasyonuna](https://www.w3.org/TR/webauthn-3/) bakın.

Tüm hataları "hata" (bug) olarak değerlendirirseniz, yanlış şeyler yaparsınız:

- hata metriklerinizi normal iptallerle kirletirsiniz
- `NotAllowedError` yığınının içinde gizlenen gerçek gerilemeleri kaçırırsınız
- kullanıcıların kurtarmasına yardımcı olmak yerine kafalarını karıştıran bir kullanıcı arayüzü sunarsınız

Bu makalede şu soruları yanıtlıyoruz:

- Gerçek trafikte en yaygın WebAuthn hata adları genellikle ne anlama gelir?
- `NotAllowedError` hatasını eyleme dönüştürülebilir gruplara (iptal vs zaman aşımı vs
  kullanılabilirlik) nasıl ayırırsınız?
- Aynı hata, işleme (koşullu kullanıcı arayüzü
  girişi vs kalıcı (modal) giriş vs geçiş anahtarı oluşturma vs
  koşullu oluşturma) bağlı olarak neden farklı anlamlara gelir?
- "Başarısız oldu" bilgisinin yeniden üretilebilir bir soruna dönüşmesi için hangi minimum bağlamı yakalamalısınız?

## Key Facts

- `NotAllowedError` bir temel neden değil, **yüzeysel bir sinyaldir**. Bağlama bağlı olarak iptal,
  zaman aşımı, "yerel kimlik bilgisi yok" veya eksik kullanıcı aktivasyonu anlamına gelebilir.
- **İşlem türü anlamı değiştirir.** Aynı `NotAllowedError`, koşullu kullanıcı arayüzü girişi, kalıcı giriş, manuel geçiş anahtarı oluşturma, koşullu
  oluşturma ve otomatik tetiklenen eklemeler sırasında farklı
  şeyler ifade eder.
- **İşlem başlangıcından itibaren geçen süre**, en çok hafife alınan sinyaldir: hemen (`<1s`),
  kullanıcı iptali (1-15s) ve zaman aşımı (30s+) temelden farklı kategorilerdir.
- `AbortError` genellikle bir yaşam döngüsü/eşzamanlılık sorunudur (gezinme, yeniden oluşturma, uçuş halindeki birden fazla istek).
- `SecurityError` neredeyse her zaman yapılandırma/bağlam ile ilgilidir ve olgun üretim
  dağıtımlarında nadirdir.
- "Tarayıcı hata adları" ve "sunucu doğrulama retleri" farklı katmanlardır. Sunucu retlerini genel istemci hataları olarak değil, açık kodlar olarak izleyin.
- **Ham hata adları tek başlarına eyleme dönüştürülemez.** Hataları gerçekten
  düzeltebileceğiniz gruplara ayırabilmek için `error.name` ile birlikte her zaman işlem türünü, zamanlamayı ve
  platform bağlamını yakalayın.
- **"Ortam" sadece Tarayıcı + İşletim Sistemi'nden ibaret değildir.** Hataları gerçekten anlamak için tam kombinasyonu izlemeniz gerekir: İşletim Sistemi Sürümü, İstemci (Tarayıcı/Uygulama Sürümü), Kimlik Doğrulayıcı
  ayarları (ör. iCloud/GPM durumu) ve belirli Donanım Modeli.
- **Giriş hataları P1, Oluşturma hataları P2'dir.** Oluşturma hataları (P2), kullanıcının vazgeçmesi nedeniyle genellikle
  daha yüksek bir hacme sahip olsa da, giriş hataları (P1) erişimi engeller ve
  derhal uyarı verilmesini gerektirir.

## 2. Üretim İçin Kısa Bir Başvuru Kılavuzu

Hata ayıklamanın engelini kaldırmak için yalnızca hızlı bir eşlemeye ihtiyacınız varsa, bu tabloyla başlayın. Ekiplerin gerçekte gösterge panellerinde ve destek biletlerinde gördüklerine
yönelik bir eğilimi vardır.

| **`error.name`**    | **Üretimde genellikle ne anlama gelir**                                                                                              | **Doğrulamak için ne kontrol edilmeli**                                                                   | **İlk eylem (Kullanıcı Deneyimi + Mühendislik)**                                                                |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `NotAllowedError`   | Kullanıcı ekranı kapattı, zaman aşımına uğradı veya kullanılabilirlik uyuşmazlığı tek bir kovada birleşti. Bu, üretimdeki en büyük hata grubudur. | hataya kadar geçen süre, QR/hibrit kullanıcı arayüzünün görünüp görünmediği, seremoninin gerçek bir kullanıcı eyleminden başlayıp başlamadığı | Beklenen bir durum olarak ele alın: kullanıcı arayüzünü geri yükleyin + geri dönüş (fallback) seçeneği gösterin |
| `AbortError`        | Uygulamanız (veya tarayıcı) seremoniyi iptal etti                                                                                       | seremoni sırasında gezinme/yeniden oluşturma; eşzamanlı WebAuthn çağrıları; `AbortController.abort()`     | Yalnızca bir isteğin beklemede kalmasını sağlayın; rota değişikliklerini önleyin; iptali normal kontrol akışı olarak ele alın |
| `SecurityError`     | Bağlam/ilke izin vermiyor                                                                                                           | köken (origin) + RP Kimliği (ID) stratejisi; iframe/gömme; HTTPS; özellik ilkesi                               | RP Kimliği/köken yapılandırmasını düzeltin; gömme ilkelerini doğrulayın; güvenli bağlam olduğundan emin olun |
| `InvalidStateError` | Durum uyuşmazlığı (genellikle mükerrer kayıt)                                                                                        | kayıt vs giriş; `excludeCredentials`; kimlik doğrulayıcıda mevcut kimlik bilgisi              | “Zaten kayıtlı” olarak değerlendirin; kullanıcı deneyimi yolunu ayarlayın; seçenek üretimini düzeltin                                 |
| `ConstraintError`   | Gereksinimler karşılanamıyor                                                                                                      | `authenticatorAttachment`, `userVerification`, yerleşik anahtar (resident key) gereksinimleri                       | Kısıtlamaları gevşetin veya alternatif bir yol/geri dönüş sağlayın. Örnek: Android'de ekran kilidi yok |
| `DataError`         | Girdiler hatalı biçimlendirilmiş/tutarsız                                                                                                    | base64url kodlaması; id/challenge/user handle formatları                                           | Kodlamayı/serileştirmeyi düzeltin; seçenek üretimine doğrulama ekleyin                                    |
| `NotSupportedError` | Platform/tarayıcı istediğiniz şeyi desteklemiyor                                                                                      | işletim sistemi/tarayıcı sürümü; özellik algılama varsayımları                                              | Hemen geri dönüş yapın; segmenti kaydedin; desteklenmeyen ortamlar için geçiş anahtarı CTA'ları (Harekete Geçirici Mesajlar) göstermekten kaçının     |
| `UnknownError`      | Platform/kimlik doğrulayıcı genel bir şekilde başarısız oldu                                                                                       | işletim sistemi güncellemelerinden sonraki sıçramalar; cihaz derlemesi (build); kimlik bilgisi yöneticisi (credential-manager) sağlayıcı sorunları                      | Yeniden deneme dostu kullanıcı deneyimi; derleme numaralarını yakalayın; segment sıçramalarını araştırın                               |

Gözden kaçırılması kolay olan bir şey: Aynı `error.name`, **işlem türüne** bağlı olarak çok farklı
şeyler ifade edebilir. Aşağıdaki bölümleri
okurken işlem bağlamını aklınızda bulundurun. Uygulamada, geçiş anahtarı oluşturma
(kayıt) hataları genellikle giriş hatalarından çok daha fazladır - yukarıdaki tablo
her ikisi için de geçerlidir, ancak hacmin büyük kısmı oluşturma aşamasındadır.

Daha sonra `NotAllowedError` üzerinde daha derinlemesine duracağız çünkü en çok göreceğiniz ve
ekiplerin en sık yanlış yorumladığı hata budur.

## 3. NotAllowedError: İşlem zaman aşımına uğradı veya izin verilmedi

`NotAllowedError` genellikle "geçiş anahtarları başarısız oldu" gibi görünür, ancak genellikle platformun
size kullanıcının işletim sistemi kullanıcı arayüzünü tamamlamadığını söylemesidir. İşin sırrı, bunu üzerinde işlem yapabileceğiniz
gruplara ayırmaktır.

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**     | **Hata mesajı**                                                                                                                                    |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge   | `NotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.`     |
| Safari, WebKit | `NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.` |
| Safari, WebKit | `NotAllowedError: This request has been cancelled by the user.`                                                                                      |
| Chrome, Edge   | `NotAllowedError: The operation is not allowed at this time because the page does not have focus.`                                                   |
| Safari, WebKit | `NotAllowedError: The document is not focused.`                                                                                                      |
| Firefox        | `NotAllowedError: Operation failed.`                                                                                                                 |

Bunların hepsi `error.name === "NotAllowedError"` olarak yüzeye çıkar. `error.message`,
tarayıcı motoruna ve altta yatan nedene göre farklılık gösterir, ancak sonuç aynıdır: seremoni
tamamlanamadı.

Bu, hem **giriş hem de geçiş anahtarı oluşturma** işlemleri için geçerlidir. Giriş sırasında (koşullu kullanıcı arayüzü,
allowList olsun veya olmasın kalıcı giriş), `NotAllowedError` tipik olarak kullanıcının
seremoniyi tamamlamadığı anlamına gelir. Geçiş anahtarı oluşturma sırasında, aynı hata
farklı nedenlerle ortaya çıkar: kullanıcı oluşturma iletişim kutusunu kapattı (koşullu oluşturma
çalışmadı veya otomatik tetiklenen bir ekleme sırasında sayfa odağını kaybetti. İşlem türü,
hatanın ne anlama geldiğini ve bu konuda ne yapmanız gerektiğini değiştirir.

**Zamanlama genellikle yeterince değer görmeyen bir sinyaldir.** Tıklamadan bir saniyeden kısa bir süre sonra oluşan bir hata
genellikle anında ret anlamına gelir (ortam bunu yapamaz, belge odaklanmamış, eksik
kapasite). Birkaç saniye sonra oluşan bir hata, kullanıcının iptal ettiğini gösterir (iletişim kutusunu gördüler ve
devam etmemeye karar verdiler). 30 saniyeden uzun bir süre sonra oluşan hata ise bir zaman aşımıdır. Yerel platformlarda,
zamanlama özellikle önemlidir: kimlik doğrulayıcı gidiş-dönüşleri,
biyometrik istemler ve kimlik bilgisi yöneticisi devir işlemleri, "çalışmadı" durumunu "kullanıcı uzaklaştı"
durumundan ayırmanıza yardımcı olan karakteristik sürelere sahiptir. Hala
bir geçiş anahtarının var olup olmadığını kolayca ayırt edemezsiniz.

### 3.1 Bağlam ile Belirsizliği Giderin

Kusursuz bir sinyale ihtiyacınız yok. Her `NotAllowedError` hatasını aynı
şekilde ele almaktan kaçınmak için yeterli bağlama ihtiyacınız vardır. Benzersiz kısıtlamalara sahip olduğu için iOS/Safari'ye
aşağıda özel bir ilgi gösterilmiştir (önceki sürümlerdeki kullanıcı etkinleştirme gereksinimleri), ancak ham hata hacminde, Windows ve Chromium tarayıcıları genellikle
diğer platformlardan daha fazla `NotAllowedError` üretir. Bu sinyaller genellikle
işin %80'ini halletmenizi sağlar:

| **Sinyal**                                                   | **Olası anlamı**                                                                                                                                                                                                                                                                               | **Sonraki adım**                                                                                                                                                                           |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Anında başarısızlık (`<1s`)                                    | Ortam reddi: yetenek yok, belgeye odaklanılmamış, koşullu oluşturma yüzeyi mevcut değil                                                                                                                                                                                               | Özellik algılamayı kontrol edin; belgenin odağı olduğundan emin olun; işlemin bu platformda desteklendiğini doğrulayın                                                                                            |
| Hızlı iptal (1-3s)                                           | Sürpriz istem / bağlam yok                                                                                                                                                                                                                                                                     | İstem zamanlamasını değiştirin; iptal edildikten sonra bekleme süresi (cooldown) ekleyin                                                                                                                                               |
| Kullanıcı süresi uzunluğunda iptal (3-15s)                                   | Kullanıcı iletişim kutusunu gördü ve devam etmemeyi seçti                                                                                                                                                                                                                                                     | Beklenen kullanıcı deneyimi; arayüzü geri yükleyin + geri dönüş seçeneği gösterin                                                                                                                                                       |
| Zaman aşımı (30s+)                                               | Seremoni, kullanıcı eylemi olmadan zaman aşımına uğradı                                                                                                                                                                                                                                                           | "Tamamlanmadı" olarak gruplayın; istemin fark edilip edilmediğini değerlendirin                                                                                                                         |
| Başarısızlıktan önce QR/hibrit kullanıcı arayüzü görünür                          | Bu cihazda yerel bir kimlik bilgisi yok. Not: Kullanıcıların QR kodla ilgili kararlarını, gerçekleşmeden önce güvenilir bir şekilde saptamak için mevcut cihazda kullanılabilecek bir kimlik bilgisinin olup olmadığını bilen bir [passkey intelligence (geçiş anahtarı istihbaratı)](https://docs.corbado.com/corbado-connect/features/passkey-intelligence) katmanı gerekir. | Geçiş anahtarı tekliflerini kısıtlayın; "Telefonu kullan" seçeneğini belirginleştirin; sürpriz QR'ı azaltın                                                                                                                            |
| iOS/Safari'de yoğunlaşmış ve tıklama/dokunma olmadan tetiklenmiş | Eksik kullanıcı aktivasyonu                                                                                                                                                                                                                                                                          | Seremoniyi gerçek bir kullanıcı hareketinden (gesture) başlatın                                                                                                                                                   |
| Koşullu oluşturma veya otomatik tetiklenen ekleme sırasında           | Otomatik doldurma mevcut değil, kimlik bilgisi zaten var veya sayfa odağını kaybetti. Koşullu oluşturma hataları, özellik başlatıldığında aniden ve yüksek hacimde ortaya çıkabilir ve bu da onu bir gecede en büyük hata kaynaklarından biri haline getirir.                                                                    | Koşullu oluşturmaya (conditional create) bakın; belge görünürlük durumunu kontrol edin; çağrıyı denemeden önce `conditionalCreate` desteğini doğrulamak için `getClientCapabilities()` kullanın |

Aynı zamanda `NotAllowedError`'un nadiren kullanıcı tarafından görülebilir olmasının nedeni de budur. Bu,
kullanıcının işlem yapabileceği bir mesaj değildir.

Bağlam sınıflandırması aynı zamanda başarı oranlarının en keskin biçimde ayrıştığı yerdir.
[Corbado Passkey Benchmark 2026 geçiş anahtarı kimlik doğrulama başarı oranı analizi](https://www.corbado.com/passkey-benchmark-2026/passkey-authentication-success-rate), büyük ölçekli B2C dağıtımlarında bilinmeyen cihaz tanımlayıcı öncelikli akışlar için 2026'nın 1. çeyreğindeki tamamlama oranını %55-95,
bilinen cihaz geri dönüşleri için ise %95-99 olarak ölçmektedir.
iOS web tanımlayıcı öncelikli akış %85-95 tamamlama (% CDA %0-5) ile sonuçlanırken, Android web %70-85 (% CDA %5-10) ve macOS web %70-85 (% CDA %10-15) oranına ulaşır. Windows web ise Windows 11'de % CDA %55-65 ve Windows 10'da %40-55 iken
%45-60 tanımlayıcı öncelikli tamamlama oranında kalır. Bilinen cihaz bağlamlarını bilinmeyen cihaz bağlamlarından ayırmadan
`NotAllowedError` hacmini okumak,
iki temelde farklı başarı rejimini birbirine karıştırır.

Üretimde önemli olan bir nüans: bazı kullanıcı aracıları zaman aşımlarını
`TimeoutError` olarak yüzeye çıkarabilir, ancak birçok ekip gösterge panellerinde zaman aşımlarının `NotAllowedError` içine yığıldığını
görür. Her iki durumda da, zaman aşımlarını "seremoni tamamlanmadı" olarak değerlendirin ve
zamanlamayı artı bağlamı kullanarak gruplandırın.

### 3.2 Kullanıcı Deneyimi Yönetimi: İptali Normal Bir Çıkış Haline Getirin

İşletim sistemi ekranı kapatıldığında veya zaman aşımına uğradığında, kullanıcı arayüzünüz anında
toparlanmalı ve zarif bir şekilde tepki vermelidir. Pratik bir kurallar dizisi:

- giriş kullanıcı arayüzünü geri yükleyin (çalışmaya devam eden yükleme simgeleri -spinner- olmasın)
- tanımlayıcı durumunu koruyun (yeniden girişi zorlamayın)
- aynı ekranda görünür bir geri dönüş seçeneği gösterin
- beklenen sonuçlar için korkutucu afişlerden kaçının

Temel kuralların ötesinde:

- İlk iptali normal olarak ele alın ve sakin bir açıklamayla yeniden deneme sunun. Yalnızca ikinci bir iptalden
  sonra geri dönüş seçenekleri önermelisiniz (bkz.
  geçiş anahtarı geri dönüşü ve kurtarma).
- Şaşıran kullanıcıların ikinci bir şans elde edebilmesi için bir bekleme süresinden (cooldown) önce en fazla üç oluşturma
  istemine izin verin (bkz. geçiş anahtarı oluşturma en iyi uygulamaları).
- Hata sayılarını oluşturma ve girişler arasında bölün, böylece elmaları elmalarla karşılaştırırsınız.
- Sürtünmenin gerçekte nerede yaşandığını görebilmek için hata oranlarını İşletim Sistemi, tarayıcı ve cihaza göre segmentlere
  ayırın (bkz. geçiş anahtarı girişi en iyi uygulamaları).

"İptalleriniz" gerçekten yüksekse, bir sonraki adım bunların arkasındaki temel nedenleri düzeltmektir:
istem zamanlaması, QR sürprizleri ve düşük kullanılabilirlik.

### 3.3 NotAllowedError'u Azaltan Mühendislik Düzeltmeleri

Metrikleri hızlıca hareket ettiren değişikliklerle başlayın:

- İstem zamanlamasını ve kullanıcı aktivasyonunu (özellikle
  iOS/Safari'de) düzeltin: Safari WebAuthn kullanıcı etkileşimli (user-activated) olaylar.
- QR/hibrit sürprizlerini azaltın: geçiş anahtarı akışları neden QR kodları gösterir ve kullanıcılar vazgeçer.
- Geçiş anahtarlarının başarılı olma ihtimali yüksek olduğunda gösterilmesi için teklifleri kısıtlayın: geçiş anahtarlarını yalnızca
  başarılı olma ihtimalleri yüksekse sunun.
- Yerel kimlik bilgisi olmadığında istemde bulunmaktan kaçınan desenler kullanın:
  WebAuthn anında arabuluculuk (immediate mediation).
- **Ağ İstikrarsızlığını Ele Alın:** Doğrulama sırasındaki ağ hataları genellikle
  genel istemci tarafı hataları olarak ortaya çıkar. Kullanıcının bağlantısı seremoni sırasında koptuğunda
  hata verilerini kaybetmemek için telemetri günlükleriniz için çevrimdışı bir kuyruk uygulayın.
- **Ortam hatalarının `NotAllowedError` grubunuzu
  şişirmesini önlemek için algılama API'leri ile seremonileri kısıtlayın.** En temel kısıtlama olarak
  `isUVPAA()` ile başlayın, ardından daha ince
  kontroller (koşullu oluşturma, koşullu alma, hibrit aktarım,
  platform kimlik doğrulayıcı) için `getClientCapabilities()` kullanın. Algılama
  API'lerinin işletim sistemi güncellemeleriyle bozulabileceğini unutmayın: iOS 26.2, WKWebView tabanlı
  tarayıcılarda geçiş anahtarları gayet iyi çalışmasına rağmen `isUVPAA()` öğesinin `false` döndürdüğü bir WebKit hatasıyla
  geldi ve bu durum iOS kullanıcılarının %10-25'i için ani `NotAllowedError` sıçramalarına neden oldu (bkz. getClientCapabilities() ile
  geçiş anahtarı algılamasını düzeltme).

### 3.4 Gelişen Hata Adları Hakkında Bir Not

Hata adları hareketli bir hedeftir. Daha ayrıntılı WebAuthn
hataları eklemeye yönelik devam eden teklifler vardır (örneğin, "hiçbir kimlik bilgisi mevcut değil" ile "kullanıcı iptal etti" durumlarını ayırmak). Şubat 2026 itibarıyla bu hiçbir tarayıcıda uygulanmamıştır,
bu nedenle bağlama ve zamanlamaya dayalı kendi neden gruplarınızı oluşturmaya devam etmekte fayda vardır. Bu çalışmaları takip etmek
isterseniz,
[WebAuthn issue #2062](https://github.com/w3c/webauthn/issues/2062) ve
["New Error Codes" açıklayıcısına](https://github.com/w3c/webauthn/wiki/Explainer%3A-New-Error-Codes-%282024-Edition%29) göz atın.

Geriye kalan hata adları daha az sıklıkla görülür ancak ortaya çıktıklarında yine de anlaşılmaya değerdir.

## 4. AbortError: İşlem iptal edildi

`AbortError`, `NotAllowedError` hatasına kıyasla hacim olarak pek yaygın değildir, ancak ortaya çıktığında yüksek düzeyde
teşhis koydurucudur: genellikle uygulamanızın
isteği geçersiz kıldığı (gezinme gerçekleşti, durum değişti veya ikinci bir istek başladı) için seremoninin tamamlanmadığı anlamına gelir.

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**     | **Hata mesajı**                                         |
| -------------- | --------------------------------------------------------- |
| Chrome, Edge   | `AbortError: The operation was aborted.`                  |
| Chrome, Edge   | `AbortError: Aborted by AbortSignal.`                     |
| Firefox        | `AbortError: signal is aborted without reason`            |
| Firefox        | `AbortError: Operation timed out.`                        |
| Safari, WebKit | `AbortError: The user aborted a request.`                 |
| Chrome         | `AbortError: CredentialContainer request is not allowed.` |

Yaygın üretim ortamı nedenleri şunlardır:

- birden fazla eşzamanlı WebAuthn çağrısı (yarışan iki istem)
- devam eden bir seremoni sırasında rota değişikliği/yeniden oluşturma
- yeniden denemeler veya durum temizleme sırasında `AbortController.abort()` çağrılması

Bunu düzeltmek için seremoniyi "kritik bir bölüm" haline getirmeye odaklanın:

- aynı anda yalnızca beklemedeki (in-flight) bir isteğe izin verin
- seremoni sırasında gezinmeyi engelleyin (veya temiz bir şekilde iptal edip kullanıcı arayüzünü geri yükleyin)
- iptali normal kontrol akışı olarak ele alın: bir yeniden deneme düğmesi ve geri dönüş yöntemi gösterin

`AbortError` hatasının gömülü yüzeylerde veya çoklu alan adlı uygulamalarda yoğunlaştığını görürseniz, kontrol etmeniz gereken bir sonraki
grup `SecurityError` grubudur.

## 5. SecurityError: WebAuthn, TLS sertifika hataları olan sitelerde desteklenmez

`SecurityError` tarayıcının size şunları söylemesidir: "Bu bağlamın istediğiniz şeyi yapmasına
izin verilmiyor." Uygulamada bu neredeyse her zaman kullanıcı davranışı değil, yapılandırmadır. Olgun üretim ortamı
dağıtımlarında `SecurityError` nadirdir çünkü bu sorunlar genellikle
entegrasyon testi sırasında yakalanır. Üretimde ortaya çıkarsa, genellikle uygun WebAuthn yapılandırması olmadan yeni bir alan adı,
yerleştirme bağlamı (embedding) veya dağıtım hedefi eklendiği anlamına gelir.

Yaygın nedenler şunlardır:

- RP Kimliği (ID) / köken uyuşmazlığı (çoklu alan adı kurulumları)
- kökenler arası (cross-origin) yerleştirme kısıtlamaları (iframe'ler)
- güvenli olmayan bağlam (HTTPS değil) veya engellenen izinler/ilkeler
- `.well-known/webauthn` veya `.well-known/assetlinks.json` dosyalarının yanlış yapılandırılmış olması, eksik olması veya
  geçici olarak kullanılamaması. Tarayıcının
  bu dosyaları getirdiği kritik pencere sırasındaki ağ sorunları arızalara neden olur. Yaygın bir kör nokta: ana sayfanız
  bakım için kapalıysa, well-known dosyaları da çevrimdışıdır ve onlara bağlı tüm bağlı taraflarda (relying parties) geçiş anahtarı seremonilerini
  bozar.

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**      | **Hata mesajı**                                                                                                                |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge    | `SecurityError: WebAuthn is not supported on sites with TLS certificate errors.`                                                 |
| Herhangi bir tarayıcı     | `SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current origin's effective domain.` |
| Chrome (iframe) | `SecurityError: The 'publickey-credentials-create' feature is not enabled in this document.`                                     |

Üretim ortamında `SecurityError` nadirdir - bunlar neredeyse her zaman entegrasyon
testi sırasında yakalanır. Ortaya çıktıklarında ise TLS sertifikası hatası en yaygın olanıdır.

En hızlı hata ayıklama döngüsü şudur:

- kullandığınız köken (origin) ve RP Kimliği girdilerini günlüğe kaydedin
- aynı bağlamda yeniden üretin (en üst düzey vs iframe,
  üretim alan adı vs hazırlık/staging)
- girişi yerleştiriyorsanız (embed), izin politikasının (permissions policy) yapılandırıldığını (örneğin
  `publickey-credentials-create` / `publickey-credentials-get`) onaylayın:
  [MDN İzin Politikası](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy/publickey-credentials-create)
- alan adı stratejinizi doğrulayın (bkz.
  ilgili kökenler)
- eğer iframe kullanıyorsanız, özellik ilkelerini (feature policies) doğrulayın (bkz.
  iframe geçiş anahtarları)

`SecurityError` ele alındıktan sonra, ciddiye alınması gereken bir sonraki grup genellikle
uygulama hatalarını (bug) gösteren hatalar dizisidir: `InvalidStateError`, `ConstraintError` ve
`DataError`.

## 6. InvalidStateError, ConstraintError, DataError: Uygulama Hataları olarak ele alın

Bu hatalar olgun bir geçiş anahtarı uygulamasında nadir olmalıdır. Ortaya çıktıklarında,
genellikle bir segment için seçenek (option) üretiminin yanlış olduğunu veya akışın
yanlış durumda olduğunu gösterirler.

### 6.1 InvalidStateError: "kimlik bilgileri zaten bağlı tarafa kayıtlı"

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**     | **Hata mesajı**                                                                                                                                    |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Safari, WebKit | `InvalidStateError: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.` |
| Chrome, Edge   | `InvalidStateError: At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.`                 |
| Chrome, Edge   | `InvalidStateError: A request is already pending.`                                                                                                   |
| Firefox        | `InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable`                                                       |

Tipik anlamlar:

- kayıt: zaten var olan bir kimlik bilgisi (mükerrer) oluşturmaya çalıştınız
- giriş: daha az yaygındır; genellikle akışın/durumun platform için tutarsız olduğu anlamına gelir

Pratik yönetim:

- eğer manuel kayıt sırasında gerçekleşirse, bunu “zaten kayıtlı” olarak değerlendirin ve
  buna göre yönlendirin
- kimlik doğrulayıcının kopyaları algılayabilmesi için kullanıcının mevcut tüm kimlik bilgisi (credential) kimliklerini `excludeCredentials` listesinin listelediğinden
  emin olun (bkz.
  excludeCredentials)
- koşullu oluşturma sırasında, `InvalidStateError`
  beklenen bir durumdur ve sessizce yoksayılmalıdır: bu, sağlayıcıda zaten bir geçiş anahtarı olduğu
  anlamına gelir. Aynı şey, koşullu
  oluşturma sırasındaki `NotAllowedError` ve `AbortError` için de geçerlidir (bkz.
  [Chrome'da koşullu oluşturma](https://developer.chrome.com/docs/identity/webauthn-conditional-create))

### 6.2 ConstraintError

Tipik anlamı: Kimlik doğrulayıcı talep ettiğiniz
kısıtlamaları karşılayamıyor.

Yaygın tetikleyiciler:

- eksik cihaz ekran kilidi (özellikle Android):
  platform biyometrik veya PIN doğrulaması gerektiriyor ancak cihazda yapılandırılmış bir
  kilit ekranı yok
- çok katı `authenticatorAttachment` veya
  yerleşik anahtar (resident key)
  varsayımları
- mevcut olmadıkları segmentlerde katı `userVerification` gereksinimleri

Düzeltme: kısıtlamaları (kabul edilebilir olduğu yerlerde) gevşetin veya alternatif bir yol sağlayın. Eksik
ekran kilidi için, bu durumu tespit etmeyi ve sessizce başarısız olmak (Android) yerine
kullanıcıları yönlendirmeyi düşünün.

### 6.3 DataError

Tipik anlamı: girdiler hatalı biçimlendirilmiş veya tutarsız.

Yaygın tetikleyiciler:

- kodlama hataları (base64 vs base64url)
- geçersiz kimlik bilgisi (credential) id'leri / challenge biçimlendirmesi

Düzeltme: WebAuthn seçeneklerini oluşturduğunuz sınırda girdileri doğrulayın ve normalleştirin. Uygulamada,
`DataError` olgun üretim sistemlerinde neredeyse hiç bulunmaz - seçenek
üretiminiz test edildiyse, bunu gösterge panellerinde görmezsiniz.

Eğer bu hatalar kontrol altındaysa, bir sonraki soru kapsama (coverage) sorusudur: ortam WebAuthn'i
beklediğiniz gibi yapamadığı için mi kullanıcılar başarısız oluyor?

## 7. NotSupportedError: Kullanıcı aracısı açık anahtar (public key) kimlik bilgilerini desteklemiyor

`NotSupportedError` bir güvenilirlik sinyali değil, bir kapsama sinyalidir. Genellikle bir
segmentin istediğiniz şeyi yapamayacağı anlamına gelir (işletim sistemi/tarayıcı çok eski, eksik yetenek, özellik
etkin değil).

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**            | **Hata mesajı**                                                                              |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| Chrome, Edge          | `NotSupportedError: The user agent does not support public key credentials.`                   |
| Firefox               | `NotSupportedError: Resident credentials or empty 'allowCredentials' lists are not supported.` |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseCreationOptionsFromJSON is not a function`                |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseRequestOptionsFromJSON is not a function`                 |
| Chrome, Edge, Firefox | `TypeError: credential.toJSON is not a function`                                               |
| Safari                | `TypeError: Can only call PublicKeyCredential.toJSON on instances of PublicKeyCredential`      |

İlk ikisi gerçek `NotSupportedError` DOMException'larıdır. `TypeError` girişleri
teknik olarak farklı bir istisna (exception) türüdür ancak aynı sınıf problemi temsil ederler: tarayıcı
veya ortam istediğinizi desteklemiyor. JSON serileştirme
`TypeError` ailesi, pratikte `NotSupportedError`
DOMException'ın kendisinden çok daha yaygındır (aşağıya bakın).

Yaygın nedenler şunlardır:

- temel WebAuthn'i desteklemeyen daha eski tarayıcılar/işletim sistemi sürümleri
- söz konusu platformda mevcut olmayan WebAuthn özellikleri talep etmek
- desteklenmeyen cihazlarda platforma özgü akışları denemek

**JSON serileştirme ailesi, üretim ortamında `NotSupportedError` sınıfı
arızaların en büyük kaynağıdır.** Teknik olarak bunlar `DOMException` olarak değil, `TypeError` (eksik yöntem) olarak ortaya çıkar,
ancak onlarla burada karşılaşacaksınız. İki farklı temel neden vardır:

1. **Tarayıcı WebAuthn JSON serileştirme yöntemlerini desteklemiyor.** Tarayıcıda
   `navigator.credentials` var ancak `PublicKeyCredential.parseCreationOptionsFromJSON` /
   `parseRequestOptionsFromJSON` yok. Bu, eski Safari ve Chrome sürümlerinde yoğunlaşan,
   bu hata ailesinin kabaca %90'ını oluşturur. İstemci kitaplığınız
   bu yöntemlere bir geri dönüş (fallback) olmadan bağlıysa, bu önemli bir hata hacmi üretir.
2. **Parola yöneticisi uzantıları `.toJSON()` yöntemini bozar.**
   Bitwarden,
   LastPass veya
   1Password gibi uzantılar
   seremoniyi bölebilir ve kimlik bilgisine benzeyen ancak gerçek
   bir `PublicKeyCredential` örneği olmayan bir nesne döndürebilir. Bu nesnede `.toJSON()` çağrılması hata (throw) verir, undefined
   döndürür veya nesne tamamen `null` olur. Bu, ailenin kabaca %10'udur ancak hata
   mesajları tarayıcıya göre değiştiği için hata ayıklaması özellikle kafa karıştırıcıdır (Safari:
   "Can only call on instances of PublicKeyCredential"; Firefox: "does not implement
   interface PublicKeyCredential").

Bu durumu ele alma şekli net ve hızlı olmalıdır:

- derhal geri dönüş (fallback) parolasına/OTP'sine (Tek Kullanımlık Parola) geri dönün
- kapsama açıklarını ölçebilmek için segmenti kaydedin
- sürekli olarak başarısız olacak segmentlerde geçiş anahtarı CTA'ları (Harekete Geçirici Mesajlar) göstermekten kaçının

Kapsama alanı iyi görünüyorsa ancak belirli segmentlerde yine de hatalar oluşuyorsa, `UnknownError`
olarak ortaya çıkan platform katmanı sorunlarıyla uğraşıyor olabilirsiniz.

## 8. UnknownError: Kimlik bilgisi yöneticisi (credential manager) ile iletişim kurarken bilinmeyen bir hata oluştu

`UnknownError`, diğer kategorilere tam olarak uymayan kimlik doğrulayıcı/işletim sistemi hataları
için her şeyi kapsayan (catch-all) bir hatadır. Genellikle geçicidir, ancak işletim sistemi
güncellemelerinden sonra da artış gösterebilir.

**Tarayıcı konsolunda görecekleriniz:**

| **Kaynak**         | **Hata mesajı**                                                                                                                       |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome (Android)   | `UnknownError: An unknown error occurred while talking to the credential manager.`                                                      |
| Herhangi bir tarayıcı        | `UnknownError: The operation failed for an unknown transient reason.`                                                                   |
| Herhangi bir tarayıcı        | `UnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made.` |
| Herhangi bir tarayıcı        | `UnknownError: Something went wrong.`                                                                                                   |
| Chrome (LastPass)  | `TypeError: Cannot use 'in' operator to search for 'type' in null`                                                                      |
| Safari (LastPass)  | `TypeError: null is not an Object. (evaluating 'key in input')`                                                                         |
| Chrome (Bitwarden) | `FallbackRequested`                                                                                                                     |

Pratik yönetim:

- yeniden deneme dostu kullanıcı deneyimi kullanın ("kullanıcıyı suçlamayın")
- mümkünse işletim sistemi/derleme (build) numaralarını ve kimlik bilgisi yöneticisi/sağlayıcı bağlamını yakalayın
- işletim sistemi
  güncellemelerinden sonra segmente özgü sıçramalara dikkat edin

Herhangi bir `DOMException` kategorisine tam olarak uymayan bir başka özel hata kaynağı:
**parola yöneticisi tarayıcı uzantıları** (örneğin
Bitwarden,
LastPass,
1Password ve diğerleri) WebAuthn
API çağrılarını bölebilir ve standart dışı yanıtlar döndürebilir. Kullanıcı iptallerine kıyasla hacimleri küçük olsa da,
bunlar belirli kullanıcı segmentlerini tutarlı bir şekilde etkilediği ve semptomların kafa karıştırıcı olduğu
için izlenmeye değerdir: döndürülen kimlik bilgisi nesnesinde eksik yöntemler, beklenmeyen hata
türleri veya belgelenmiş herhangi bir WebAuthn hatasıyla eşleşmeyen hatalı biçimlendirilmiş
yanıtlar. Bunlar genellikle `UnknownError` veya sınıflandırılmamış istisnalar olarak ortaya çıkar. Eğer
işletim sistemi düzeyinde bir açıklaması olmayan, belirli tarayıcılarda yoğunlaşan hata sıçramaları
görürseniz, işin içinde bir kimlik bilgisi yöneticisi (credential manager) uzantısı olup olmadığını kontrol edin.

Şimdiye kadar web tarayıcısı hata adlarını ele aldık. Ancak, yerel uygulamalar da (native apps) yayınlıyorsanız, hata
ortamı farklıdır - ve bazı açılardan çok daha iyidir.

## 9. Yerel Uygulamalar (iOS ve Android) Hakkında Birkaç Söz

Yukarıdaki her şey web tarayıcılarını kapsar. Yerel uygulamalar - ASAuthorization
framework ile iOS, Credential Manager ile Android - aynı
temel hata kategorilerini paylaşır, ancak önemli şekillerde farklılık gösterir:

1. **"Kimlik bilgisi yok" farklı bir sinyaldir.** Web'de tarayıcılar, gizlilik için "hiçbir kimlik bilgisi
   mevcut değil" ve "kullanıcı iptal etti" durumlarını aynı `NotAllowedError` çatısı altında
   birleştirir. Yerel ortamda,
   iOS'ta (`ASAuthorizationController`) `preferImmediatelyAvailableCredentials` veya
   Android'de (`GetCredentialRequest`) `setPreferImmediatelyAvailableCredentials(true)`
   kullanmak, işletim sistemine
   yalnızca cihazda zaten var olan kimlik bilgilerini sunmasını ve hiçbiri yoksa derhal
   başarısız olmasını söyler.
   Bu size web'in sağlayamayacağı temiz bir "kimlik bilgisi yok" dönüşü sağlar.

2. **Kimlik bilgisi (credential) sağlayıcı durumu görülebilir.** Yerel platformlar bazı koşullarda hiçbir kimlik bilgisi sağlayıcısının (Google Password Manager,
   iCloud Keychain,
   1Password vb.) yüklü,
   yapılandırılmış veya varsayılan olarak ayarlanmış olmadığını size söyleyebilir
   ve buna tepki vermenizi sağlar. Web'de bu
   bilgiler şeffaf olmayan `NotAllowedError` mesajlarının ardına gizlenir.

3. **Hata mesajları daha spesifiktir.** Kullanıcı uygulamayı yüklediğinden - ve
   böylece bağlı taraf (relying party) ile bir güven ilişkisi
   kurduğundan - işletim sistemi daha fazla tanılayıcı ayrıntıyı yüzeye çıkarır. Uygulama zaten
   cihazdayken, web tarayıcılarını belirsiz olmaya zorlayan gizlilik
   hususları aynı şekilde geçerli değildir. iOS, mesajları kullanıcının
   cihaz dilinde yerelleştirilmiş olarak döndürür. Android, neden (cause) zincirlerine sahip yapılandırılmış
   hata türleri döndürür. Bu, hata ayıklamayı kolaylaştırır ancak hata yönetiminizin yerelleştirmeyi
   ve platforma özgü hata formatlarını hesaba katması gerektiği anlamına gelir.

### 9.1 iOS (ASAuthorization Framework)

iOS, geçiş anahtarı hatalarını ASAuthorization framework'ü aracılığıyla yüzeye çıkarır. Tüm hatalar
`authorizationController(controller:didCompleteWithError:)` temsilci (delegate) geri çağırmasında (callback) `NSError`
nesneleri olarak gelir.

**Mesaj dizesine göre değil, domain + koda göre sınıflandırın.** Birincil hata alanı (domain)
`com.apple.AuthenticationServices.AuthorizationError`
(`ASAuthorizationError.errorDomain`)'dır. Hatayı `let nsError = error as NSError` ile dönüştürün (cast)
ve `.domain` ve `.code` ile eşleştirin. Üretimde asla `.localizedDescription` üzerinde
eşleşme yapmayın - Apple'ın mesajları 30'dan fazla dile çevrilmiştir ve işletim sistemi sürümleri
arasında değişebilir. Aşağıda listelenen mesaj dizeleri günlüklerdeki (log) hataları tanımak için yararlıdır,
ancak sınıflandırma kriteri değildirler.

**Ortak ASAuthorizationError kodları:**

| **Kod** | **Ad**                                | **Sürümden İtibaren** | **Ne anlama gelir**                                                                                                                                                                                                                                                                                                     |
| -------- | --------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1000     | `Unknown`                               | iOS 13    | Üretimde görünmemelidir. Her şeyi kapsayan (catch-all) genel durum.                                                                                                                                                                                                                                                                   |
| 1001     | `Canceled`                              | iOS 13    | Kullanıcı geçiş anahtarı ekranını kapattı. Genel olarak en yaygın hata - `NotAllowedError` muadili. Boş `userInfo` ve altında yatan bir hata olmayan temiz bir sinyal.                                                                                                                                                           |
| 1002     | `InvalidResponse`                       | iOS 13    | Framework düzeyinde bozulma. Pratikte nadirdir.                                                                                                                                                                                                                                                                         |
| 1003     | `NotHandled`                            | iOS 13    | Hiçbir sağlayıcı isteği ele almadı. Yetkilendirmeleri (entitlements) ve kimlik bilgisi sağlayıcı yapılandırmasını kontrol edin.                                                                                                                                                                                                                            |
| 1004     | `Failed`                                | iOS 13    | Genel başarısızlık. `localizedDescription` asıl nedeni içerir (ör. "Application with identifier X is not associated with domain Y"). `userInfo` bir `FailureReason` dizesi içerebilir, ancak `NSUnderlyingErrorKey` her zaman doldurulmaz - alan adı ilişkilendirme hataları temel hata (underlying error) için nil döndürür. |
| 1005     | `NotInteractive`                        | iOS 15    | `preferImmediatelyAvailableCredentials` kullanıldığında kullanılabilir kimlik bilgisi yok. Bu, temiz bir "bulunamadı" sinyalidir - "bu cihazda geçiş anahtarı yok" durumunun iOS'taki muadili. Kullanıcı arayüzü gösterilmedi.                                                                                                                        |
| 1006     | `MatchedExcludedCredential`             | iOS 18    | Bu cihazdaki bu RP için halihazırda bir geçiş anahtarı var. Mükerrerleri (duplicate) tespit etmek için temiz sinyal - boş `userInfo`, `NSUnderlyingErrorKey` yok. Sınıflandırma, dize (string) eşleştirme olmadan çalışır.                                                                                                                                |
| 1007     | `CredentialImport`                      | iOS 18.2  | Kimlik bilgisi içe aktarma işlemi başarısız oldu.                                                                                                                                                                                                                                                                                             |
| 1008     | `CredentialExport`                      | iOS 18.2  | Kimlik bilgisi dışa aktarma işlemi başarısız oldu.                                                                                                                                                                                                                                                                                             |
| 1009     | `PreferSignInWithApple`                 | iOS 26    | Kullanıcı geçiş anahtarı yerine Apple ile Giriş Yap'ı tercih ediyor. iOS 26'da yeni.                                                                                                                                                                                                                                                          |
| 1010     | `DeviceNotConfiguredForPasskeyCreation` | iOS 26    | Cihazda parola veya iCloud Keychain yapılandırması eksik. Bilinen iOS 26 simülatörü hatası: yapılandırma doğru olsa bile 1010 değerini döndürür (fiziksel cihazlarda bu sorun yeniden oluşturulmaz).                                                                                                                                         |

Üretim ortamı için en önemli ayrım: **iOS 18'den beri, mükerrer kimlik bilgileri
kendi hata kodlarını olan 1006 (`MatchedExcludedCredential`)'yı döndürür.**
iOS 17 ve daha önceki sürümlerde, mükerrer kimlik bilgileri
kod 1004 (`Failed`) içinde gizliydi.
iOS 18 ve sonrasında ise bu ayrım metinsel (textual) değil,
yapısaldır (farklı hata kodu).

**Yaygın çalışma zamanı hataları (günlük düzeyi referansı):**

Bu mesajlar, belirli hata senaryoları için `localizedDescription` veya `userInfo`
içinde görünür. Bunları, programatik sınıflandırma için değil,
günlük aramaları (log search) ve hata ayıklama için kullanın.

| **Mesaj (İngilizce yereli)**                                                    | **Temel Kod** | **Notlar**                                                                                                                                      |
| ------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Application with identifier <TeamID.BundleID> is not associated with domain X` | 1004 (`Failed`)     | Uygulamanın İlişkili Alan Adları (Associated Domains) yetkisi (entitlement), bağlı tarafla (relying party) eşleşmiyor. Sunucunuzdaki `apple-app-site-association` dosyasını düzeltin.            |
| `Couldn't communicate with a helper application.`                               | 1004 (`Failed`)     | Kimlik bilgisi sağlayıcı uzantısı (extension) yanıt veremedi. Geçici - yeniden denemek uygundur.                                                         |
| `Request already in progress for specified application identifier.`             | 1004 (`Failed`)     | Biri beklemedeyken yinelenen bir ASAuthorization isteği tetiklendi. Uygulamada yarış (race) koşulu.                                                |
| `Stolen Device Protection is enabled and biometry is required.`                 | 1004 (`Failed`)     | iOS 17+ Çalınan Cihaz Koruması (Stolen Device Protection), alışılmadık konumlarda biyometrik kimlik doğrulamayı engeller. Geliştiriciler tarafından eyleme dönüştürülemez, ancak kullanıcıya gösterilmeye değerdir. |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.)`               | Ayrı bir alan (domain)     | Cihazlar arası kimlik doğrulama (hibrit/CABLE) Bluetooth el sıkışması başarısız oldu.                                                                         |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.)`               | Ayrı bir alan (domain)     | Cihazlar arası kimlik doğrulama Bluetooth bağlantısı başarısız oldu.                                                                                       |

**Yerelleştirilmiş "kimlik bilgisi yok" mesajları (kod 1005):**

`preferImmediatelyAvailableCredentials` ayarlandığında ve geçiş anahtarı yoksa, iOS kullanıcının cihaz dilinde yerelleştirilmiş bir mesajla
1005 (`NotInteractive`) kodunu döndürür. Bu,
yerel uygulamalara özgüdür - web tarayıcıları bu sinyali asla açığa çıkarmaz. Mesaj her zaman
`The operation couldn't be completed.` (İşlem tamamlanamadı.) ile başlar ve ardından yerelleştirilmiş metin gelir:

| **Dil**          | **Mesaj**                                                                          |
| --------------------- | ------------------------------------------------------------------------------------ |
| Çince (Basitleştirilmiş)  | `没有可用于登录的凭证。`                                                             |
| Vietnamca            | `Không có sẵn thông tin để đăng nhập.`                                               |
| Arapça                | `لا تتوفر بيانات اعتماد لتسجيل الدخول.`                                              |
| İspanyolca               | `No hay ninguna credencial disponible para iniciar sesión.`                          |
| Çince (Geleneksel) | `沒有可用於登入的憑證。`                                                             |
| Korece                | `로그인을 위한 자격 증명이 없습니다.`                                                |
| Fransızca (Kanada)       | `Aucun identifiant disponible pour la connexion.`                                    |
| Portekizce (Brezilya)   | `Nenhuma credencial disponível para login.`                                          |
| Fransızca (Fransa)       | `Aucune information d'identification n'est disponible pour procéder à la connexion.` |
| Tayca                  | `ไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ`                                               |
| İtalyanca               | `Non ci sono credenziali disponibili per l'accesso.`                                 |
| Felemenkçe                 | `Geen inloggegevens beschikbaar.`                                                    |
| Japonca              | `ログイン用の資格情報がありません。`                                                 |
| Türkçe               | `Oturum açmak için kullanılabilecek kimlik bilgisi yok.`                             |

İngilizce (English-locale) cihazlar tipik olarak ASAuthorization framework'ü
yerelleştirilmiş bir hata döndürmeden önce "kimlik bilgisi yok" durumunu API seviyesinde çözerler, bu nedenle yukarıda hiçbir İngilizce varyant görünmez.
Programlı olarak, bu dizeleri (string) ayrıştırmak yerine daima 1005 koduyla eşleşme sağlayın.

### 9.2 Android (Credential Manager API)

Android, geçiş anahtarı hatalarını Credential Manager API (`androidx.credentials`) aracılığıyla yüzeye çıkarır.
Hata mesajları, birincil bir mesaj ve genellikle ek ayrıntılar içeren bir `cause` (neden) içerir. iOS ile karşılaştırıldığında, Android
daha yapılandırılmış hata türleri ve yapılandırma sorunları için
daha açık nedenler sağlar.

**Kullanıcı iptali ve kimlik bilgisi (credential) tespiti:**

| **Hata**                                         | **Notlar**                                                                                                                                                                                                 |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `User cancelled the operation`                    | Kullanıcı geçiş anahtarı istemini kapattı. `NotAllowedError` muadili. Not: Credential Manager ayrıca farklı bir kod yolundan `User canceled the request` (ABD yazılışı) değerini de döndürür - her ikisi de aynıdır. |
| `Excluded credential matches existing credential` | Bu kimlik bilgisi kimliği (ID) için zaten bir geçiş anahtarı mevcut. `InvalidStateError` muadili. iOS'un aksine, bu mesaj kullanıcı iptalinden belirgin bir şekilde farklıdır.                                                          |
| `No create options available.`                    | Hiçbir uygun kimlik bilgisi sağlayıcı oluşturma isteğini işleyemiyor. Genellikle Google Play Hizmetlerinin güncel olmadığı veya hiçbir kimlik bilgisi sağlayıcısının geçiş anahtarı oluşturmayı desteklemediği anlamına gelir.                                    |

**Yapılandırma ve güvenlik hataları:**

| **Hata**                                                                      | **Notlar**                                                                                                                                         |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Passkeys not supported for this app`                                          | Digital Asset Links (`assetlinks.json`) eksik veya uygulamanın imza sertifikası parmak izini içermiyor. `SecurityError` muadili. |
| `Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.json` | `assetlinks.json` dosyası HTTP 200 yerine bir yönlendirme (redirect) döndürüyor. Android, dosyayı yönlendirme olmadan tam URL'de talep eder.                  |
| `The incoming request cannot be validated`                                     | Credential Manager, isteği Digital Asset Links'e karşı doğrulayamıyor.                                                                     |
| `RP ID cannot be validated.`                                                   | WebAuthn seçeneklerindeki bağlı taraf kimliği (relying party ID), `assetlinks.json` ile eşleşmiyor.                                                                    |
| `Screen lock is missing.`                                                      | Cihazda yapılandırılmış PIN, desen veya biyometrik veri yok. Geçiş anahtarları kullanıcı doğrulaması gerektirir. `ConstraintError` muadili.                     |
| `Cannot find an eligible account.`                                             | Cihazda geçiş anahtarı oluşturmaya uygun hiçbir Google hesabı yok (nadir, tipik olarak özel kurumsal kurulumlar).                                      |

**Platform ve kimlik doğrulayıcı hataları:**

| **Hata**                                                                                | **Notlar**                                                                                                                                                                                                                                          |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Unsuccessful result from folsom activity.`                                              | Google Play Hizmetleri dahili hatası. "Folsom", geçiş anahtarı işlemleri için bir GMS bileşenidir. Geçici - yeniden denemek uygundur.                                                                                                                       |
| `Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics.` | Senkronize edilmiş bir geçiş anahtarı var ancak cihaz özel anahtarını çözemiyor. Google Şifre Yöneticisi eşitleme durumu tutarsız - kimlik bilgisi başka bir cihazdan senkronize edildi ancak şifre çözme anahtarı mevcut değil. Geliştiriciler tarafından eyleme dönüştürülemez. |
| `Operation was interrupted` (neden: `The UI was interrupted - please try again.`)        | Credential Manager kullanıcı arayüzü başka bir aktivite (gelen arama, ekran döndürme, arka plana alınan uygulama) tarafından kesintiye uğratıldı. `AbortError` muadili.                                                                                                     |
| `Unknown credential error`                                                               | Hiçbir belirli hata türü geçerli olmadığında her şeyi kapsayan (catch-all) genel hata. Genellikle geçicidir.                                                                                                                                                                        |
| `timeout` (neden: `Canceled`)                                                            | Credential Manager işlemi, kullanıcı biyometrik doğrulamayı tamamlamadan önce zaman aşımına uğradı.                                                                                                                                                       |

## 10. Hepsini Bir Araya Getirmek: Hata Sınıflandırması (Taxonomy)

Aşağıdaki diyagram, yukarıda tartışılan tüm katmanların (Altyapı,
Ortam, İşlem türü, Sınıflandırma ve Algılama) uçtan uca nasıl bağlandığını gösterir.
Hata izlemenizi tasarlarken aklınızda bulundurmanız gereken zihinsel model budur.

```mermaid
flowchart TD
    %% Global Styles
    classDef expected fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef unexpected fill:#ffebee,stroke:#c62828,stroke-width:2px;
    classDef network fill:#fff3e0,stroke:#ef6c00,stroke-dasharray: 5 5;
    classDef env fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px;
    classDef action fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

    %% --- LEFT SIDE: NETWORK & SERVER ---
    subgraph Infrastructure ["Altyapı (Sunucu/Ağ)"]
        direction TB
        ServerErr["Sunucu Tarafı Hatası<br/>500 / Mantık Hatası"]:::network
        NetErr["Ağ Hatası<br/>Zaman Aşımı / 400 Kötü İstek"]:::network

        ServerErr & NetErr -->|Şu Şekilde Görünür:| ClientManifest["İstemci Tarafı Genel Hatası"]
    end

    %% --- CENTER: THE ENVIRONMENT STACK (From Sketch) ---
    subgraph Environment ["Ortam (İstemci Tarafı)"]
        direction TB

        %% Layer 1: Platform Type
        subgraph Type ["Katman 1: Platform"]
            Web["Web / Tarayıcı"]
            Native["Yerel (Native) / Uygulama"]
        end

        %% Layer 2: OS Context
        subgraph OS_Layer ["Katman 2: İşletim Sistemi ve Sürüm"]
            OS_Web["İşletim Sistemi: Windows, macOS, Linux"]
            OS_Nat["İşletim Sistemi: iOS, Android"]
            OS_Ver["İşletim Sistemi Sürümü / Ayarları<br/>(Ekran Kilidi, Biyometri)"]

            Web --> OS_Web
            Native --> OS_Nat
            OS_Web & OS_Nat --> OS_Ver
        end

        %% Layer 3: Client Software
        subgraph Client_Layer ["Katman 3: İstemci Yazılımı"]
            Browser["Tarayıcı: Chrome, Safari, Edge<br/>+ Sürüm"]
            App["Yerel Uygulama / WebView<br/>+ Uygulama Sürümü"]

            OS_Ver --> Browser
            OS_Ver --> App
        end

        %% Layer 4: WebAuthn Operation
        subgraph Op_Layer ["Katman 4: WebAuthn İşlemi"]
            OpType{"İşlem Türü"}

            Login["Giriş<br/>(navigator.credentials.get)"]
            Reg["Kayıt<br/>(navigator.credentials.create)"]

            Browser & App --> OpType
            OpType --> Login
            OpType --> Reg
        end

        %% Layer 5: Sub-types & Complexity
        subgraph Modality ["Katman 5: Modalite ve Karmaşıklık"]
            Sub_CUI["CUI / Koşullu Kullanıcı Arayüzü"]
            Sub_Auto["Otomatik İşlem"]
            Sub_CDA["CDA / Cihazlar Arası Kimlik Doğrulama"]

            Login & Reg --> Sub_CUI
            Login & Reg --> Sub_Auto
            Login & Reg --> Sub_CDA
        end
    end

    %% --- BOTTOM: CLASSIFICATION & ACTION (The "What here?" section) ---
    subgraph Analysis ["Hata Analizi ve Çalışma Zamanı"]
        direction TB

        %% Classification
        Classification{"Sınıflandırma"}

        Exp["Beklenen Hata<br/>(Kullanıcı Seremoniyi İptal Etti)"]:::expected
        Unexp["Beklenmeyen Hata<br/>(Sistem/Çökme/Bilinmeyen)"]:::unexpected

        ClientManifest --> Classification
        Sub_CUI & Sub_Auto & Sub_CDA --> Classification

        Classification --> Exp
        Classification --> Unexp

        %% Detection Logic
        subgraph Detection ["Algılama Hedefleri"]
            P1["P1: Giriş Sorunları"]
            P2["P2: Oluşturma Sorunları"]
            Baseline["Temel Kaymayı Algıla<br/>(Artan Beklenen Hatalar)"]
            NewErr["Yeni Anomalileri Algıla<br/>(Artan Beklenmeyen Hatalar)"]
        end

        Exp --> Baseline
        Unexp --> NewErr
        Exp & Unexp --> P1 & P2

        %% Actionable Outcomes
        subgraph Action ["Azaltma Eylemleri"]
            Fix["Düzeltme (Hotfix) / Yeni Sürüm Dağıt"]:::action
            Fallback["Otomatik Geri Dönüşü (Fallback) Etkinleştir<br/>(Geçiş Anahtarını Devre Dışı Bırak)"]:::action
        end

        P1 & P2 & NewErr --> Fix
        P1 & P2 & NewErr --> Fallback
    end

    %% Connectors
    Infrastructure -.-> Environment
```

Temel içgörü: ham bir `error.name` ancak bunu Ortamın hangi katmanının ürettiğini,
hangi İşlemin (Operation) çalıştığını ve hatanın Beklenen (Expected) mi yoksa Beklenmeyen (Unexpected) mi
olduğunu bildiğinizde anlam kazanır. Aşağıdaki bölümlerde nelerin günlüğe kaydedileceği ve bunların üzerinde nasıl eylemde bulunulacağı
ele alınmaktadır.

## 11. Hataları hata ayıklanabilir hale getirmek için neleri günlüğe kaydetmelisiniz

Bu makaledeki hata sınıflandırmalarının çoğu tek başına istemci tarafı sinyalleriyle
yapılabilir. Sadece ön yüzde çalışan (frontend-only) bir gözlemlenebilirlik (observability) SDK'sı,
WebAuthn hatalarının büyük çoğunluğunu sınıflandırmak için yeterli bağlamı yakalar.
Corbado'nun gözlemlenebilirlik SDK'sının mimarisi de bu şekildedir: istemci tarafı
katmanı hata atfı, zamanlama, işlem bağlamı ve platform algılamayı yönetir. Sunucu tarafı
günlüğe kaydetme ise yalnızca arka ucun (backend) görebildiği hatalar için ikinci bir katman ekler.

Temel gereksinim: her girişim (attempt) uçtan uca birleştirilebilir olmalıdır.
Paylaşılan bir korelasyon kimliği (ör. `auth_flow_id`), istemci tarafı bağlamını sunucu doğrulama sonucuyla birleştirir.

### 11.1 İstemci Tarafı Sinyalleri (Frontend SDK)

| **Sinyal**                                 | **Neden önemli**                                                                                                                   |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `error.name` + normalleştirilmiş neden grubu    | Ham tarayıcı hatası + sizin sınıflandırmanız                                                                                              |
| İşlem türü                             | Koşullu kullanıcı arayüzü, kalıcı (modal) giriş, manuel oluşturma, koşullu oluşturma, otomatik ekleme. **CDA (Cihazlar Arası Kimlik Doğrulama)** kendine has karmaşık bir yapıdadır.   |
| Tam Ortam Bağlamı                   | İşletim Sistemi + Sürüm, Tarayıcı + Sürüm, **Donanım Markası/Modeli**, **Kimlik Doğrulayıcı Ayarları** (örneğin, GPM etkin mi?)                           |
| Kimlik doğrulayıcı / kimlik bilgisi yöneticisi bağlamı | Uzantı ve sağlayıcı bozulması                                                                                                      |
| İşlemin başlangıcından hataya kadar geçen süre         | Anında ret (`<1s`) vs kullanıcı iptali (1-15s) vs zaman aşımı (30s+)                                                                 |
| Ağ / Bağlantı Durumu              | Ağ hataları sıklıkla istemci hataları olarak ortaya çıkar. Kullanıcının çevrimdışı olup olmadığını izleyin ve bağlantı geri geldiğinde göndermek üzere **günlükleri sıraya koyun (queue)**. |
| QR/hibrit kullanıcı arayüzünün görünüp görünmediği              | Yerel hataya karşın cihazlar arası hata                                                                                                        |
| Korelasyon kimliği (`auth_flow_id`)            | Sunucu günlükleriyle (logs) birleştirmek için                                                                                                        |

### 11.2 Sunucu Tarafı Sinyalleri (Arka Uç Doğrulaması)

Sunucu doğrulama hataları, tarayıcı bir kimlik bilgisi ve imzalı bir challenge döndürdükten sonra
meydana gelir. Bunlar, istemci tarafı `DOMException` adlarıyla aynı kaba karıştırılmak yerine
açık kodlara sahip yapılandırılmış hatalar olmalıdır. Bakınız:
WebAuthn sunucu uygulaması.

| **Sinyal**                               | **Neden önemli**                                                                                                                                                                             |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Challenge uyuşmazlığı / süresi dolmuş challenge   | Oturum zamanlaması veya tekrar (replay) sorunları                                                                                                                                                                |
| Köken (origin) / RP Kimliği uyuşmazlığı                  | Çoklu alan adı (multi-domain) yapılandırma hataları                                                                                                                                                                |
| Geçersiz imza / kimlik bilgisi bulunamadı | Silinmiş veya bozuk kimlik bilgisi. Yaygın kullanım durumu: Kullanıcının sunucu tarafında zaten sildiği bir geçiş anahtarı ile koşullu kullanıcı arayüzü girişi yapmak. İstemci ve sunucu kimlik bilgisi listelerini senkronize tutmak için Signal API kullanın. |
| Kullanıcı tanıtıcı (user handle) uyuşmazlığı                     | Hesap eşleme sorunları                                                                                                                                                                         |
| Korelasyon kimliği (`auth_flow_id`)          | İstemci tarafı bağlamıyla birleştirmek için                                                                                                                                                                  |

Adım adım ayrılmaları (drop-offs) ve adımlar arası dönüşümü gösteren tam bir huni modeli (funnel model) istiyorsanız, şuraya bakın:
bırakmaları anlamak için geçiş anahtarı telemetrisi.

[Watch on YouTube](https://www.youtube.com/watch?v=wnrXJzvBjsU)

Bu veriler yerindeyken, sonuç basit hale gelir: çoğu "hata" ya kullanıcı deneyimi (UX) düzeltmelerine, kapsama (coverage) düzeltmelerine
veya yapılandırma düzeltmelerine dönüşür. Ancak bu sınıflandırmayı kendiniz oluşturmak ve
sürdürmek önemli ve devam eden bir iştir.

## 12. Hata Adlarının Ötesi: Corbado Ham Hataları Nasıl Eyleme Dönüştürülebilir Sinyallere Çeviriyor

Yukarıdaki günlük (logging) kontrol listesi ham sinyalleri yakalar. Ölçekli üretimde,
tek başına `error.name` yeterli değildir. Bu sınıflandırmayı kendinizin oluşturması
önemli ve devam eden bir iştir: hata mesajları her tarayıcı ve işletim sistemi sürümüyle değişir,
parola yöneticisi sağlayıcıları
seremoni davranışını değiştiren güncellemeler yayınlar ve her özellik lansmanıyla
yeni hata imzaları ortaya çıkar.

### 12.1 Neden tek başına `error.name` yeterli değildir

Aynı `NotAllowedError`, tarayıcıların sizin için
ayırmadığı üç boyuta bağlı olarak altı farklı anlama gelebilir:

| **Boyut**                | **Tarayıcıların size verdiği** | **Gerçekte ihtiyacınız olan**                                                             | **Örnek**                                                                                                 |
| ---------------------------- | -------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **İşlem bağlamı**        | `NotAllowedError`          | Bu koşullu kullanıcı arayüzü mü, kalıcı (modal) giriş mi, manuel oluşturma mı, koşullu oluşturma mı, yoksa otomatik ekleme miydi? | Android, bir girişi reddetme (beklenen) ile oluşturma başarısızlığı (beklenmeyen) için aynı "unknown error" hatasını döndürür |
| **Zamanlama**                   | Süre verisi yok           | Anında ret (`<1s`) vs kullanıcı iptali (1-15s) vs zaman aşımı (30s+)                             | 200ms = ortam reddi; 5s = kullanıcı iletişim kutusunu gördü ve iptal etti; 35s = zaman aşımı                            |
| **Platform + kimlik doğrulayıcı** | Genel `error.name`       | Her hata için işletim sistemi, tarayıcı, sürüm, kimlik bilgisi yöneticisi (credential manager)                               | Chrome'da "kullanıcı iletişim kutusunu kapattı" ve Safari'de "otomatik doldurma kullanılamıyor" durumlarının her ikisi de `NotAllowedError` olarak ortaya çıkar    |

### 12.2 Corbado'nun gözlemlenebilirlik SDK'sı neleri yakalar

[Corbado'nun gözlemlenebilirlik SDK'sının](https://www.corbado.com/pricing) çözmek için
oluşturulduğu sorun budur. Mevcut
geçiş anahtarı uygulamanızın üzerine oturan, herhangi bir WebAuthn sunucusu ve herhangi bir IDP ile çalışan ve
her WebAuthn hatasını üç boyutun tamamında otomatik olarak sınıflandıran hafif bir ön uç (frontend) entegrasyonudur:

| **Yetenek**                       | **Ne yapar**                                                                                                                                                                                                                                                        |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Hata atfı**                | Her seremoni girişimi ile işletim sistemi, işletim sistemi sürümü, tarayıcı, tarayıcı sürümü ve kimlik doğrulayıcıyı yakalar                                                                                                                                                                         |
| **İşlem modu**                   | Her bir hatayı belirli işleme (koşullu kullanıcı arayüzü, kalıcı giriş, manuel oluşturma, koşullu oluşturma, otomatik ekleme) bağlar, böylece aynı `NotAllowedError` farklı temel nedenlere ayrılır                                                                             |
| **İşlem başından itibaren zamanlama**         | Tahmin yürütmeden anında retleri, kullanıcı iptallerini ve zaman aşımlarını ayırt etmek için seremoninin başlamasından itibaren geçen süreyi kaydeder                                                                                                                                               |
| **Akıllı hata sınıflandırması** | Çeşitli **Ortamlarda** (İşletim Sistemi, Donanım, Ayarlar) normalleştirerek yalnızca isme değil, tam hata bağlamına göre eşleşir. **CDA** vs. Yerel gibi farklı hata gruplarına öncelik verir ve **Beklenen (Kullanıcı İptali)** ile **Beklenmeyen (Sistem Arızası)** hataları birbirinden ayırır. |
| **Parola yöneticisi parçalanması**   | Kimlik bilgisi yöneticisi uzantılarının (Bitwarden, 1Password, LastPass) seremonileri kesip standart dışı yanıtlar döndürdüğünü algılar ve uzantı kaynaklı arızaları platform arızalarından ayırır                                                                         |

Bu, **Observe (Gözlem)** katmanıdır: uygulamanızı değiştirmeden
neler olup bittiğine dair görünürlük (visibility).

### 12.3 Hata ayıklamanın İki Yolu: Yukarıdan Aşağıya ve Aşağıdan Yukarıya

Corbado'nun yönetim konsolu (management console) iki inceleme yolunu destekler:

**Yukarıdan aşağıya (gösterge panelinden temel nedene):**

1. **İki farklı anomali türü için izleme yapın:**
    - **Artan Beklenen Hatalar (Temel Kayma / Baseline Drift):** Belirli bir ortamda (örneğin, iPhone 15'te
      iOS 18.2) "kullanıcı iptallerinde" kademeli bir
      artış görüldü mü? Bu genellikle işletim sistemi güncellemesiyle gelen bir kullanıcı deneyimi sürtünmesini (UX friction) gösterir.
    - **Artan Beklenmeyen Hatalar (Sıçramalar):** Tamamen yeni bir hata veya hatalarda ani
      bir artış. Bu genellikle kırılmaya neden olan bir değişikliğe (dahili IDP yığın güncellemesi) veya yeni bir
      tarayıcı sürümündeki gerilemeye (regression) işaret eder.
2. **Etkiye göre önceliklendirin:**
    - **P1: Giriş Sorunları.** Giriş başarı oranları düşerse derhal uyarı verin.
    - **P2: Oluşturma Sorunları.** Eğilimleri (trends) izleyin, ancak oluşturma akışlarındaki
      "kullanıcı iptali" artışları için mühendisleri uyandırmaktan kaçının.
3. **Ortamın detaylarına inin:** Sorunun küresel mi yoksa
   "Android 14'lü Samsung cihazlara" mı özgü olduğunu izole etmek için ayrıntılı boyutları (Donanım,
   Kimlik Doğrulama Ayarları) kullanın.
4. **Azaltma (Mitigation):** Kritik bir sıçrama tespit edilirse, bir **Durdurma Anahtarınız (Kill Switch)**
   hazır olsun. Söz konusu ortam için geçiş anahtarlarını otomatik veya manuel olarak
   devre dışı bırakın ve siz sorunu araştırırken giriş oranlarını korumak için OTP/Parola'ya geri dönün (fallback).

**Aşağıdan yukarıya (hata modellerinden etkiye):**

1. Hata sınıflandırması görünümünden başlayın. Sınıflandırılmış hata kalıplarını (patterns) ve hacimlerini gözden geçirin.
2. Yeni kalıplar (örneğin farklı bir hata mesajı ile gelen yeni bir tarayıcı sürümü) ortaya çıktıkça hata eşlemelerini (mappings) düzeltin.
3. Hatalar, KPI değişiklikleriyle çapraz ilişkilendirilir ve gösterge panellerinde not (annotation) olarak yüzeye
   çıkarılır; böylece belirli bir hata kalıbındaki artış, otomatik olarak etkilediği metriğe bağlanır.

Her iki yol da birleşir: yukarıdan aşağıya yaklaşım bir şeylerin yanlış olduğunu söyler, aşağıdan yukarıya yaklaşım
nedenini söyler.
[Yapay Zeka (AI) Analitik Asistanı](https://www.corbado.com/ai-analytics-assistant), hem hata verileri hem de benimseme metrikleri
üzerinden doğal dilde sorular sormanıza izin vererek bu iki yolu birbirine bağlar.

Bu sinyalleri eyleme dökmek isteyen ekipler,
seremonileri otomatik olarak kısıtlamak, kayıt (enrollment) istemlerini optimize etmek ve bozulan geçiş anahtarı
durumlarını iyileştirmek için [passkey intelligence (geçiş anahtarı istihbaratı)](https://docs.corbado.com/corbado-connect/features/passkey-intelligence) ekleyen **Adopt (Benimseme)** adımına geçebilir. Düzenlemeye tabi ortamlar
veya hiper ölçekli (hyperscale) dağıtımlar için, **Enterprise (Kurumsal)** sürümü
tek kiracılı (single-tenant) barındırma, SIEM entegrasyonu ve PSD2 uyumlu
yapılandırma ekler.

## 13. Sonuç

WebAuthn hata adları bir hüküm değildir. Bunlar ipuçlarıdır - ve yalnızca bunları işlem türüne, zamanlamaya ve platform bağlamına
bağladığınızda eyleme dönüştürülebilir hale gelirler.

- **Gerçek üretimde en yaygın WebAuthn hata adları ne anlama gelir?** Çoğu, küçük bir
  katmanlar kümesiyle eşleşir: kullanıcı kontrol akışı (`NotAllowedError`), uygulama yaşam döngüsü/eşzamanlılığı
  (`AbortError`), güvenlik bağlamı/yapılandırması (`SecurityError`), veya seçenek (option)/durum (state) hataları
  (`InvalidStateError`, `ConstraintError`, `DataError`). Hacmin büyük bir kısmı
  `NotAllowedError`'dur ve bunun da çoğu beklenen bir davranıştır (kullanıcının istemi kapatması).
- **`NotAllowedError` hatasındaki belirsizliği nasıl giderirsiniz?** Zamanlama (anında ret vs kullanıcı
  iptali vs zaman aşımı), QR/hibrit göstergesi (kullanılabilirlik uyuşmazlığı), kullanıcı aktivasyon bağlamı
  (özellikle iOS/Safari'de) ve işlem türünü (koşullu kullanıcı arayüzü vs kalıcı (modal) giriş
  vs geçiş anahtarı oluşturma vs koşullu oluşturma) kullanın. Tüm `NotAllowedError` durumlarına tek bir
  arıza türü (failure mode) muamelesi yapmayın.
- **İşlem türü neden önemlidir?** Bir
  koşullu kullanıcı arayüzü girişi sırasındaki aynı `error.name`,
  koşullu oluşturma veya manuel geçiş anahtarı oluşturma (kullanıcı iletişim kutusunu kapattı) durumundan
  tamamen farklı bir sinyaldir. İşlem türünü hatayla birlikte günlüğe kaydetmek, genel
  `NotAllowedError` hatasını eyleme dönüştürülebilir bir gruba çeviren şeydir.
- **Hangi minimum bağlam hataların ayıklanabilir olmasını sağlar?** `error.name`, işlem türü,
  işlem başından hataya kadar geçen süre, akış türü, QR/hibrit kullanıcı arayüzünün (UI) gösterilip gösterilmediği,
  İşletim Sistemi/tarayıcı/cihaz (sürümler dahil), bir korelasyon kimliği (`auth_flow_id`) ve açık kodlar olarak
  sunucu doğrulama retlerini yakalayın.

Tüm hata türlerini kesen iki temel kural: ham tarayıcı hatalarını asla
kullanıcılara göstermeyin - her zaman açık bir geri dönüş (fallback) yolu sağlayın - ve yerel denemeler ile QR/hibrit cihazlar arası denemeleri
ayırın, çünkü bunlar farklı nedenlerle başarısız olurlar ve farklı düzeltmelere
ihtiyaç duyarlar.
Ölçeklendiğinde, tarayıcılar, işletim sistemi sürümleri ve kimlik bilgisi yöneticileri genelinde hata sınıflandırmasını korumak devam eden bir
iştir. Bunu sıfırdan oluşturmak yerine, bakımı yapılan bir kalıp (pattern) kütüphanesine
sahip bir gözlemlenebilirlik (observability) SDK'sı kullanmayı düşünün.

## Sıkça Sorulan Sorular

### Bir kullanıcının geçiş anahtarı istemini iptal etmesi ile cihazda geçiş anahtarı olmaması arasındaki farkı nasıl anlarım?

Web üzerinde tarayıcılar, gizlilik nedenleriyle her iki durumu da `NotAllowedError` olarak birleştirir, bu nedenle bunları doğrudan ayırt edemezsiniz. Zamanlamayı bir gösterge olarak kullanın: 1 saniyenin altındaki bir hata genellikle ortam reddini veya eksik kapasiteyi gösterirken, 1-15 saniye kullanıcının iletişim kutusunu görüp kapattığını gösterir. Yerel iOS ve Android uygulamalarında, istekten önce `preferImmediatelyAvailableCredentials` ayarını yapmak, herhangi bir kullanıcı arayüzü gösterilmeden önce size temiz bir "kimlik bilgisi yok" sinyali (iOS kodu 1005, Android `GetCredentialRequest`) verir.

### Geçiş anahtarları çoğu kullanıcı için çalışıyor gibi görünse de WebAuthn hata oranım neden bu kadar yüksek?

Optimize edilmiş büyük ölçekli geçiş anahtarı dağıtımlarında, kaydedilen WebAuthn hatalarının %95'inden fazlası sistem arızaları değil, beklenen kullanıcı iptalleridir. "Kullanıcı istemi reddetti" durumunu gerçek arızalardan ayırmadan ham `error.name` sayılarını izlemek, hata metriklerini şişirir ve `NotAllowedError` hacmi içinde gizlenen gerçek gerilemeleri maskeler. Sayımlarınızı işlem türüne göre ayırın ve kullanıcı iptal gruplarını `SecurityError`, `ConstraintError` ve `DataError` gibi beklenmeyen hatalardan ayrı değerlendirin.

### iOS'ta ASAuthorizationError kodu 1005 ne anlama geliyor ve bunu nasıl kullanmalıyım?

iOS kodu 1005 (`NotInteractive`), `ASAuthorizationController` üzerinde `preferImmediatelyAvailableCredentials` ayarlandığında cihazda hiçbir geçiş anahtarı bulunmadığı ve kullanıcıya hiçbir kullanıcı arayüzü gösterilmediği anlamına gelir. Bu, web tarayıcılarının gizlilik kısıtlamaları nedeniyle sağlayamadığı temiz "bu cihazda geçiş anahtarı yok" sinyalidir. Apple'ın mesajları 30'dan fazla dile çevrildiğinden ve işletim sistemi sürümleri arasında değişebildiğinden, sınıflandırmayı her zaman `localizedDescription` üzerinde değil, sayısal kod üzerinde yapın.

### Koşullu oluşturma veya otomatik tetiklenen geçiş anahtarı ekleme akışı sırasında NotAllowedError hatasını nasıl ele almalıyım?

Koşullu oluşturma sırasında `NotAllowedError`, `AbortError` ve `InvalidStateError` beklenen sonuçlardır ve hata olarak sunulmak yerine sessizce yoksayılmalıdır. `NotAllowedError` otomatik doldurmanın kullanılamadığını veya sayfanın odağını kaybettiğini gösterirken, `InvalidStateError` sağlayıcıda zaten bir geçiş anahtarı olduğu anlamına gelir. Çağrıyı denemeden önce, `conditionalCreate` desteğini doğrulamak için `getClientCapabilities()` kullanın ve hata sayılarınızı şişirmekten kaçınmak için belge görünürlük durumunu kontrol edin.

### WebAuthn hatalarını gerçekten ayıklanabilir hale getirmek için error.name ile birlikte hangi bağlamı günlüğe kaydetmeliyim?

İşlem türünü (koşullu kullanıcı arayüzü, kalıcı giriş, manuel oluşturma, koşullu oluşturma veya otomatik ekleme), işlemin başlangıcından hataya kadar geçen süreyi, işletim sistemi sürümünü, tarayıcı sürümünü, donanım modelini, QR/hibrit kullanıcı arayüzünün görünüp görünmediğini ve sunucu tarafı günlükleriyle birleştirmek için bir korelasyon kimliğini (ID) yakalayın. Meydan okuma (challenge) uyuşmazlığı, geçersiz imza ve kimlik bilgisi bulunamadı gibi sunucu doğrulama hataları, istemci tarafı `DOMException` adlarıyla aynı grupta karıştırılmamalı, açık yapılandırılmış kodlar olarak günlüğe kaydedilmelidir. Bu sinyaller birlikte, hataların büyük çoğunluğunun tahmin yürütmeden eyleme dönüştürülebilir gruplara ayrılmasına olanak tanır.
