Erreurs Firebase App Check : corriger 403, « App attestation failed » et jetons non valides
Les erreurs App Check surviennent à l’une de deux étapes : quand l’application obtient un jeton auprès de son fournisseur d’attestation (Play Integrity, App Attest, reCAPTCHA), ou quand un service Firebase vérifie ce jeton. Si la première étape échoue, la seconde échoue aussi : ne vous arrêtez donc pas à l’erreur du service, cherchez d’abord l’erreur d’échange de jetons et corrigez les valeurs enregistrées pour votre plateforme. Les émulateurs, les simulateurs et localhost ne peuvent pas, par nature, passer l’attestation : ils utilisent un jeton de débogage.
En bref
- Trouvez d’abord l’étape qui a échoué. Si l’échange de jetons se termine par une erreur 403, c’est un problème de configuration du fournisseur ; si seul le service refuse les requêtes, sans erreur d’échange, le jeton est absent ou non valide. Les distinguer par le message
- En développement, utilisez un jeton de débogage. Les émulateurs, les simulateurs, localhost et les builds signés avec la clé de débogage ne passent pas une vraie attestation. Comment l’enregistrer
- Chaque plateforme a des valeurs qui doivent correspondre. Sur Android, le SHA-256 du certificat de signature ; sur Apple, le Team ID et l’environnement production d’App Attest ; sur le web, les domaines de la clé reCAPTCHA. Causes par plateforme
- Depuis le 2 novembre 2026, App Check est appliqué automatiquement à AI Logic. Vous ne pouvez le reporter que jusqu’au 21 janvier 2027. Que faire
Trouver l’étape en échec d’après le message
| Message | Étape en échec |
|---|---|
Android : Error returned from API. code: 403 body: App attestation failed. | Obtention du jeton. Le serveur App Check n’a pas accepté le résultat de Play Integrity. |
Apple : The server responded with an error … HTTP status code: 403 | Obtention du jeton. Le résultat d’App Attest ou de DeviceCheck n’a pas été accepté. |
Web : HTTP status: 403. (appCheck/fetch-status-error), puis appCheck/throttled | Obtention du jeton. Le résultat reCAPTCHA n’a pas été accepté, et le SDK ne réessaie pas pendant 24 heures. |
Cloud Storage : Firebase App Check token is invalid. (dans le SDK Web, storage/unauthorized-app) | Utilisation du jeton. Il est absent ou non valide. |
Fonctions appelables (callable) : functions/unauthenticated | Utilisation du jeton. Une fonction avec enforceAppCheck: true l’a refusé. Un jeton Auth incorrect donne le même code ; c’est la ligne AppCheck token was rejected du journal de la fonction qui permet de les distinguer. |
Realtime Database : Provided AppCheck credentials for the app named ... are invalid | Utilisation du jeton. Il n’est pas valide. |
Firebase AI Logic : 403 PERMISSION_DENIED: ... you must enforce Firebase App Check. | Utilisation du jeton. Voir la section AI Logic. |
Faute de jeton, les requêtes adressées au service ne portent aucun jeton valide (le SDK Web joint à la place un jeton factice). Même si l’erreur visible vient du service, vérifiez donc d’abord si une erreur d’obtention du jeton apparaît aussi dans les journaux. Après un échec, le SDK attend avant de réessayer : sur le web, 24 heures après une erreur 403 ou 404 ; sur Android et Apple, 24 heures après une erreur 400 ou 404 ; et jusqu’à 4 heures après les autres erreurs. Cet état ne vit qu’en mémoire : après avoir corrigé la configuration, redémarrez l’application ou rechargez la page avant de vérifier.
Un jeton de débogage pendant le développement
Les émulateurs et les simulateurs ne sont pas reconnus comme des appareils valides, et les builds de débogage qui ne sont pas sur Google Play ne passent pas Play Integrity. Par principe, on n’ajoute pas localhost à une clé reCAPTCHA. Dans ces environnements, activez le fournisseur de débogage et enregistrez dans la console le jeton qu’il écrit dans les journaux.
- N’activez le fournisseur de débogage que dans les builds de développement.
// Android (Kotlin): com.google.firebase:firebase-appcheck-debug Firebase.appCheck.installAppCheckProviderFactory( if (BuildConfig.DEBUG) DebugAppCheckProviderFactory.getInstance() else PlayIntegrityAppCheckProviderFactory.getInstance(), ) // iOS (Swift): before FirebaseApp.configure() #if DEBUG AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory()) #endif // Web: before initializeAppCheck(), in development builds only self.FIREBASE_APPCHECK_DEBUG_TOKEN = true; // Flutter (firebase_app_check 0.5+) await FirebaseAppCheck.instance.activate( providerAndroid: kDebugMode ? const AndroidDebugProvider() : const AndroidPlayIntegrityProvider(), providerApple: kDebugMode ? const AppleDebugProvider() : const AppleAppAttestWithDeviceCheckFallbackProvider(), ); - Lancez l’application et cherchez le jeton de débogage dans les journaux. Les SDK récents l’affichent sous la forme
Firebase App Check debug token: <UUID>(dans logcat sur Android, la console Xcode sur Apple, la console du navigateur sur le web). - Enregistrez le jeton. Dans la console Firebase, ouvrez l’onglet Applications (Apps) d’App Check, puis choisissez Gérer les jetons de débogage (Manage debug tokens) dans le menu ⋮ de l’application. Chaque application peut en avoir jusqu’à 20.
- Les jetons changent. Un nouveau jeton est créé sur Android quand vous effacez les données de l’application ou la réinstallez, sur Apple quand vous la réinstallez, et sur le web quand vous utilisez un autre profil de navigateur ou effacez les données du site. Le nouveau jeton doit être enregistré à son tour.
- En CI, transmettez un jeton déjà enregistré. Sur le web, la chaîne du jeton dans
self.FIREBASE_APPCHECK_DEBUG_TOKEN; sur Android, l’argument d’instrumentationfirebaseAppCheckDebugSecret; sur Apple, la variable d’environnement du schémaAppCheckDebugToken; dans Flutter, le paramètredebugToken. - Traitez le jeton comme un mot de passe. Ne le mettez pas dans le dépôt, et gardez le fournisseur de débogage et son jeton hors des builds de production.
Causes par plateforme
Android (Play Integrity)
| Symptôme | Cause | Correctif |
|---|---|---|
| Échoue seulement sur les émulateurs ou les builds de débogage | Les émulateurs ne sont pas des appareils valides, et Google Play ne connaît pas la signature de débogage. | Jeton de débogage |
| L’application téléchargée depuis Play échoue | Vous avez enregistré le SHA-256 de la clé d’importation. Avec la signature d’application Play, Google signe à nouveau l’application avec la clé de signature d’application. | Enregistrer dans App Check le SHA-256 du certificat de la clé de signature d’application affiché sur la page Gérer la signature d’application Play (Manage Play app signing) de la Play Console |
| Une application distribuée hors de Play échoue | Par défaut, seules les versions de l’application reconnues par Google Play (PLAY_RECOGNIZED) passent. | Dans les paramètres Play Integrity d’App Check, passer PLAY_RECOGNIZED à Non requis (Not required) et relever l’intégrité minimale de l’appareil à Intégrité de l’appareil (Device integrity) |
Échoue à mesure que les utilisateurs augmentent (TOO_MANY_REQUESTS, -8) | Les projets Cloud non associés dans la Play Console sont limités à 10 000 requêtes Play Integrity par jour. | Dans la section API Play Integrity de la Play Console, associer le projet Firebase avec Associer un projet Cloud (Link Cloud project), puis demander plus de quota si besoin. Seules les applications présentes sur Google Play peuvent être associées. |
Apple (App Attest, DeviceCheck)
| Symptôme | Cause | Correctif |
|---|---|---|
| Échoue sur le simulateur | Le simulateur n’est pas un appareil valide. | Jeton de débogage |
| Seuls les builds installés depuis Xcode échouent | Ajouter la capability App Attest règle l’environnement sur development, et App Check n’accepte pas les résultats de cet environnement. Les builds TestFlight et App Store utilisent toujours production. | Régler App Attest Environment sur production dans le fichier d’entitlements |
| Échoue sur tous les appareils | Le Team ID enregistré dans Firebase n’est pas celui de l’application. | Saisir le bon Team ID pour l’application Apple dans les paramètres du projet Firebase |
| Échoue sur Mac ou dans les extensions d’application | App Attest n’est pas pris en charge dans ces environnements. | Ajouter DeviceCheck comme fournisseur de secours. Pour DeviceCheck, enregistrer dans App Check la clé (.p8) créée sur le site Apple Developer et son ID de clé |
| Flutter : le fournisseur choisi n’est pas utilisé sur les appareils réels | Appeler d’abord FirebaseApp.configure() dans AppDelegate fait ignorer providerApple. | Supprimer configure() d’AppDelegate et n’utiliser que Firebase.initializeApp() en Dart |
Web (reCAPTCHA)
| Symptôme | Cause | Correctif |
|---|---|---|
| Échoue seulement sur le site déployé | Le domaine ne figure pas dans la liste des domaines de la clé reCAPTCHA. | Ajouter le domaine dans les paramètres de la clé. La prise en compte peut prendre jusqu’à 30 minutes |
| Échoue sur localhost | Les clés de production n’incluent pas localhost. | Jeton de débogage |
| Échoue après un changement de clé | La classe du fournisseur et la valeur enregistrée dans Firebase ne vont pas ensemble. | Clé Enterprise : ReCaptchaEnterpriseProvider dans le code et la clé de site dans Firebase. Clé v3 : ReCaptchaV3Provider dans le code et la clé secrète dans Firebase |
| Échoue encore après la correction | Après une erreur 403 ou 404, le SDK ne retente pas l’échange de jetons pendant 24 heures. | Recharger la page. Cet état ne vit qu’en mémoire. |
AI Logic : App Check appliqué automatiquement depuis le 2 novembre 2026
Depuis le 2 novembre 2026, Firebase applique automatiquement App Check à Firebase AI Logic dans les projets qui ne l’appliquaient pas. Les requêtes sans jeton valide sont bloquées, de même que celles des versions de l’application publiées sans App Check. Deux erreurs d’AI Logic mentionnent App Check.
403 PERMISSION_DENIED: To access this model, you must enforce
Firebase App Check.
403 PERMISSION_DENIED: Firebase AI Logic has been deactivated in this
project. To resume using Firebase AI Logic, you must enforce Firebase
App Check.- La première signifie qu’une requête sans jeton App Check valide a appelé un modèle qui fait souvent l’objet d’abus. Configurez App Check et appliquez-le. Pendant le développement, utilisez le fournisseur de débogage.
- La seconde signifie que le projet a été jugé inactif et n’applique pas App Check. Si vous l’appliquez déjà et que l’erreur apparaît quand même, vérifiez la protection contre la relecture (replay protection) : quand elle est activée, y compris en mode Monitor only, seuls les jetons à usage limité (limited-use tokens) sont acceptés.
Si des versions sans App Check sont encore entre les mains des utilisateurs, vous pouvez repousser la date à laquelle App Check est appliqué. Il suffit de changer la date du sélecteur Applique (Enforces) sur la ligne Firebase AI Logic de l’onglet API (APIs) d’App Check ; le 21 janvier 2027 est la dernière date possible. Si la ligne indique déjà Appliqué (Enforced), changez la date, puis, dans Configurer (Set up) sur cette ligne, passez la Protection de référence (Baseline protection) à Unenforced (monitoring only) et la protection contre la relecture à Disabled : ce n’est qu’ainsi qu’App Check cesse d’être appliqué. Google le déconseille : publiez donc avant cette date une version qui intègre App Check.
Avant de l’appliquer à d’autres services
- Regardez d’abord les métriques. L’onglet API (APIs) d’App Check répartit les requêtes de chaque service en requêtes validées (Verified), de clients obsolètes (Outdated client, sans jeton), d’origine inconnue (Unknown origin) et non valides (Invalid). Une fois App Check appliqué, seules les requêtes validées passent : appliquez-le quand presque toutes les requêtes récentes sont validées.
- Les anciennes versions de l’application sont bloquées. Les versions sans le SDK App Check voient leurs requêtes refusées dès que vous appliquez App Check.
- La prise d’effet peut prendre jusqu’à 15 minutes. Ne jugez pas le résultat dès qu’App Check est appliqué.
- Dans Cloud Functions, App Check ne peut être appliqué qu’aux fonctions appelables. Ajoutez
enforceAppCheck: trueet redéployez pour que cela prenne effet. App Check ne peut pas être appliqué aux fonctionsonRequest: vérifiez-y vous-même le jeton avec l’Admin SDK.
Sources
- Présentation d’App Check, activer l’application d’App Check, surveiller les métriques, limite de jetons de débogage (REST)
- Fournisseur Play Integrity, quota Play Integrity, fournisseur de débogage pour Android
- Fournisseur App Attest, fournisseur DeviceCheck, fournisseur de débogage pour Apple, environnement App Attest (Apple), où App Attest est disponible (Apple)
- Fournisseur reCAPTCHA Enterprise, fournisseur reCAPTCHA v3, créer une clé reCAPTCHA, fournisseur de débogage pour le web
- Fournisseur de débogage pour Flutter,
activate()dansfirebase_app_check - App Check pour AI Logic, codes d’erreur d’AI Logic, App Check pour Cloud Functions, vérifier les jetons dans votre propre backend
- Code source des SDK : limitation des tentatives sur le web, jeton factice sur le web, refus de Storage, message d’erreur Android, nouvelles tentatives sur Android, nouvelles tentatives sur Apple, refus des fonctions appelables
