Política de Broken Functionality: por qué Google rechaza una app que en tu móvil funciona perfectamente
Google te manda una línea: tu app no cumple la política de Broken Functionality. Sin stack trace, sin captura, sin pasos para reproducirlo. Instalas la misma build de release en tu propio móvil y funciona. ¿Qué cambias entonces antes de volver a enviarla? Normalmente nada del código: el revisor nunca llegó tan lejos.
Última actualización: julio de 2026
Lo que dice realmente la política de Broken Functionality
Broken Functionality es una sección de la política de Google Play «Funcionalidad, contenido y experiencia de usuario». La regla es una frase: no se permiten apps que fallen, se cierren de forma inesperada, se congelen o funcionen de forma anómala. Google da exactamente tres ejemplos: apps que no se instalan, apps que se instalan pero no cargan y apps que cargan pero no responden.
Léelo otra vez y fíjate en lo que NO aparece. Nada sobre tu arquitectura, tu cobertura de tests, tu framework o la calidad de tu código. Es una política de comportamiento. Describe lo que pasó en un dispositivo, en una sesión, en una red, durante una revisión que dura minutos. Esa distinción lo es todo: esto no se arregla escribiendo mejor código, sino haciendo que la app sobreviva a los primeros cinco minutos con un desconocido.
Política de Google Play: funcionalidad, contenido y experiencia de usuario
Localiza tu línea exacta de rechazo
El cuerpo del correo es una plantilla que reciben miles de desarrolladores. La línea del problema que va debajo no lo es: es lo más parecido a un informe de error que vas a recibir. Busca la tuya en la primera columna.
| La línea que te dio Google | Lo que vio el revisor | La causa realmente más probable | Haz esto antes de volver a enviar |
|---|---|---|---|
App doesn't install | El artefacto nunca llegó a ser una instalación funcional en el dispositivo de revisión. | Un fallo en la instalación, no un error de ejecución: un minSdkVersion por encima del dispositivo de prueba, un split de ABI o de densidad ausente, o una firma que no cuadra. | Instala el artefacto que Google tiene de verdad —descárgalo de tu canal de pruebas internas, no de Android Studio— en un dispositivo que encaje con el minSdk que declaras. |
App installs, but doesn't load | Se abrió y se quedó en una pantalla que nunca llegó a ser usable. | El splash está esperando algo que la sesión del revisor no tiene: un token de autenticación, una primera llamada a la API, una carga de configuración remota, un token de FCM. | Arranca la app en frío en modo avión, sin sesión en caché. Si se queda colgada en vez de mostrar un error, acabas de reproducir tu rechazo. |
App loads, but crashes | Un fallo en los primeros minutos de la sesión. | Un camino de primer uso que nunca tocas en local. Tu dispositivo tiene datos; el del revisor no, así que una lista vacía o un perfil nulo tumban la pantalla. | Informe previo al lanzamiento → pestaña Estabilidad. El stack trace ya está ahí, de un dispositivo real, en el lado de Google. |
App loads, but is not responsive | Los toques no hacían nada, o la interfaz se congeló. | Trabajo en el hilo principal durante el arranque: una llamada de red síncrona, un parseo grande de JSON, una migración de base de datos. | Sácalo del hilo principal. Android lanza un ANR a los 5 segundos sin atender un evento de entrada; un revisor abandona mucho antes que el sistema. |
App contains icon(s) or button(s) that are not responsive | Determinados controles no hacían nada al tocarlos. | Controles muertos: una tarjeta «Próximamente», un CTA detrás de un feature flag apagado, una fila de menú sin destino, un enlace que da 404. | Con una instalación limpia y sin cuenta, toca todos los controles de la app. Lo que no responda se conecta o se quita: no hay tercera opción. |
Broken Functionality no es Limited Functionality
Son dos secciones distintas de la misma página de políticas, y sus soluciones son opuestas. Broken Functionality significa que tu app falla. Limited Functionality and Content significa que tu app funciona perfectamente y aun así no merece instalarse: una WebView que envuelve tu web, una única pantalla estática, un visor de un solo PDF. Confundirlas te lleva a construir funciones cuando lo que tienes que arreglar es un cuelgue.
| Broken Functionality | Limited Functionality and Content | |
|---|---|---|
| La regla | «No permitimos apps que fallen, se cierren de forma inesperada, se congelen o funcionen de forma anómala.» | «No permitimos apps que solo tengan funcionalidad y contenido limitados.» |
| Qué salió mal | Tu app no hizo lo que dice que hace. | Tu app hizo exactamente lo que dice. Ese es el problema. |
| Disparador típico | Splash colgado, fallo en el primer arranque, botón muerto, backend inalcanzable. | Una web dentro de una WebView, una pantalla de texto, un envoltorio sin valor nativo. |
| La solución | Hacer que el flujo existente funcione en un dispositivo limpio. | Construir algo que una pestaña del navegador no pueda hacer, o no publicarlo. |
| El movimiento equivocado | Añadir funciones. | Corregir errores. |
Nuestra propia guía de rechazos de Google Play metía las dos en un solo punto. Estaba mal, y es buena parte del motivo por el que existe esta página. Why Google Play rejects apps
Tu app funciona. El revisor aun así no pudo entrar.
Aquí es donde vive de verdad la mayoría de estos rechazos, y casi nadie escribe sobre ello. Tu build está bien. Tu máquina no es la del revisor. Repasa esta lista antes de tocar una línea de código.
- Una pantalla de inicio de sesión sin credenciales de prueba que funcionen. El revisor abre tu app, ve un formulario, no tiene nada que escribir y la cierra. Desde fuera eso es indistinguible de una app que «se instala pero no carga».
- OTP por SMS o correo. Diste una cuenta de demostración, pero el código llega a un teléfono que está en tu mesa. Google es explícito: si tu app normalmente exige verificación en dos pasos o una contraseña de un solo uso, tienes que aportar credenciales reutilizables que se lo salten.
- Un backend con geobloqueo o con lista blanca de IP. La revisión no se hace desde tu oficina. Si tu API solo admite el CIDR de la oficina, o la app bloquea países en los que no vendes, el revisor aterriza en tu pantalla de error. La redacción de Google es que los datos de acceso deben ser válidos «independientemente de la ubicación del usuario», y que un geobloqueo exige credenciales maestras.
- Una URL base de staging o localhost en la build de release. Suena demasiado tonto para pasar y pasa continuamente: una variante de build mal configurada, un .env sin cambiar, una URL de depuración que sobrevive a un merge. Tu portátil resuelve ese host por la VPN de la oficina o por una línea de /etc/hosts. El dispositivo de revisión no.
- Un backend que duerme. El escalado a cero y los planes gratuitos arrancan en frío entre 5 y 30 segundos. Tu primera petición de la mañana es lenta y has dejado de notarlo. Todas las peticiones del revisor son la primera petición de la mañana.
- Un feature flag que se quedó apagado. Publicaste con la bandera remota desactivada, pensando en encenderla tras la aprobación. El revisor prueba lo que tiene delante, encuentra una pantalla vacía y rechaza.
- Una clave de API caducada, o una clave de Maps/Firebase restringida a tu certificado de firma de depuración. Play App Signing vuelve a firmar tu release con un SHA-1 distinto al de tu clave de depuración. A partir de ahí fallan todos los mosaicos y todas las llamadas: solo en producción, nunca en tu máquina.
Cada uno de estos casos produce una app impecable en tu mesa y rota en revisión. Y ninguno aparecerá jamás en tus informes de fallos, porque no falló nada.
¿Cómo doy una cuenta de prueba a los revisores de Google Play?
En Play Console, ve a Política y programas → Contenido de la app → Datos de inicio de sesión → Empezar (o Gestionar), pulsa «+ Añadir instrucciones nuevas» y rellena los datos de acceso. Puedes añadir hasta cinco juegos. Después abre la página Resumen de publicación y pulsa «Enviar para revisión». Si lo único que has cambiado son las credenciales, no necesitas subir un .aab nuevo.
Los requisitos de Google para esos datos, en sus propias palabras:
- Accesibles en todo momento, reutilizables y válidos independientemente de la ubicación del usuario.
- Mantenidos en todo momento y sin errores.
- Facilitados en inglés.
- Si el acceso no es numérico ni alfanumérico —un código QR o un código de barras—, genera una URL estática y súbela a Play Console.
- Si el usuario fija su propio PIN o contraseña para llegar al contenido de la app, da instrucciones claras.
- Si dependes de Iniciar sesión con Google, Facebook o similares, aporta toda la información de la cuenta más instrucciones detalladas.
El fallo del que nadie te avisa: tu cuenta de demostración funciona… y luego deja de funcionar. Caduca una prueba de 30 días. Un limitador de tasa la bloquea en la tercera revisión. Alguien del equipo resetea la base de datos de pruebas un viernes. «Accesible en todo momento» está haciendo mucho trabajo en esa frase: trata la cuenta de revisión como datos de producción.
Con una cuenta tampoco basta. El revisor tiene que llegar a todas las funciones que anuncia tu ficha de la tienda. Si la pestaña premium exige un plan de pago, la cuenta de demostración tiene que tener ya ese permiso concedido.
Google Play: requisitos para facilitar datos de inicio de sesión para la revisión
El informe previo al lanzamiento te miente si tienes pantalla de acceso
La prueba Robo solo puede escribir tus credenciales de prueba en widgets estándar de Android y en Compose. No puede iniciar sesión a través de un flujo de autenticación basado en WebView ni manejar controles que tu app dibuje en OpenGL. Así que una app de React Native o Flutter con login en WebView obtiene un informe limpio y sin fallos que cubre exactamente una pantalla: la de inicio de sesión. Informe en verde, app rechazada.
Añade una cuenta de prueba desechable en Probar y publicar → Pruebas → Informe previo al lanzamiento → Configuración. Nunca pongas ahí una cuenta real. Después lee la pestaña Capturas antes que la de Estabilidad: si las 20 capturas son tu pantalla de acceso, ya has encontrado tu rechazo y nunca fue un fallo.
Google Play: usar un informe previo al lanzamiento para detectar problemas
¿A partir de cuándo lento cuenta como congelado?
Android lanza un ANR cuando tu app no responde a un evento de entrada en 5 segundos. El mismo límite de 5 segundos se aplica a un receptor de emisiones en primer plano y a llamar a startForeground() después de startForegroundService(). Esos son los límites del sistema. La paciencia de un revisor es mucho más corta, y contra el aburrimiento no hay apelación.
Para situar las cifras que la propia Google considera inaceptables: los umbrales de mal comportamiento de Android vitals están en un 1,09 % de tasa de fallos percibidos por el usuario y un 0,47 % de tasa de ANR percibidos, en el conjunto de dispositivos, o un 8 % en un único modelo. Si los cruzas, tu ficha recibe un aviso, pero puedes estar muy por debajo y aun así ser rechazado, porque una revisión es una sesión, no una distribución.
Así se ve en la práctica. Un desarrollador publicó la cadena exacta «App installs, but doesn't load» en el foro Android Builder, insistiendo en que no había nada mal; al pedirle detalles, mencionó que «a veces la pantalla 1 se queda parada unos segundos». Sin fallo. Sin ANR. Por debajo del límite de 5 segundos del sistema. Rechazado igualmente.
Lo que nos lleva a la forma más eficiente de ganarse este rechazo: la pantalla de splash que tapa un backend muerto. Se ve idéntica tanto si tu API respondió en 200 ms como si no respondió nunca. Ponle un tiempo de espera —3 segundos y luego una pantalla de error de verdad con un botón Reintentar—. Una app que dice «No se ha podido contactar con el servidor» es una app que funciona teniendo un mal día. Una app que gira eternamente es «installs, but doesn't load».
Android developers: ANR · Umbrales de Android vitals
Reprodúcelo en 30 minutos
- Ponte en el estado del revisor. Un emulador reseteado o un dispositivo de repuesto: sin cuenta iniciada, sin sesión en caché, sin VPN, sin línea en /etc/hosts, con datos móviles en vez del wifi de la oficina. Instala el artefacto que tiene Google: descarga el .aab de tu canal de pruebas internas en vez de compilar en local. Solo este paso encuentra la mayoría de los casos.
- Abre el informe previo al lanzamiento (Probar y publicar → Informe previo al lanzamiento). Primero la pestaña Capturas: ¿pasó el rastreador de tu pantalla de acceso? Después Estabilidad para el stack trace y Rendimiento para el tiempo de arranque.
- Ejecuta adb logcat durante un arranque en frío, filtrado a tu proceso: adb logcat --pid=$(adb shell pidof -s com.your.package). Busca la petición que nunca vuelve. Ese es tu splash colgado.
- Revisa Crashlytics y Play Console → Calidad → Android vitals → Fallos y ANR, filtrando por el código de versión que enviaste. Si los dos están vacíos, tu problema nunca fue un fallo: vuelve a la lista del entorno del revisor de más arriba.
- Recorre tu propia ficha de la tienda. Abre cada captura, lee cada frase de funcionalidad y haz exactamente eso en la app, en el dispositivo limpio y en orden.
Tu ficha de la tienda es el guion de pruebas
Los revisores no adivinan qué se supone que hace tu app. Leen tu ficha y tus capturas, y luego comprueban. Eso convierte tu propio texto de marketing en la especificación con la que te evalúan. La captura de una función que sale el mes que viene es hoy una función rota. Y también lo son una tarjeta «Próximamente», una fila de Ajustes que no abre nada y un enlace de soporte que apunta a un 404. O quitas la captura o publicas la función.
¿Volver a enviar o apelar?
Vuelve a enviar si has encontrado una causa concreta y la has arreglado: nuevo código de versión, Contenido de la app actualizado, Enviar para revisión. Apela solo cuando estés seguro de que no hay nada roto y puedas demostrarlo: tienes una apelación por cada medida de cumplimiento y la respuesta suele llegar en unos 2 días laborables.
Un consejo directo: la mayoría de los hilos del tipo «¡¡¡mi app no tiene nada roto!!!» en la comunidad de Play terminan con el desarrollador encontrando un muro de acceso o un backend dormido. Haz primero la pasada de 30 minutos. Si apelas y te equivocas, has gastado tu única apelación y una semana de ingresos.
En cualquier caso, cuenta qué ha cambiado. Los revisores de Google trabajan con la misma línea única que tú. Pega esto en el formulario de apelación, o en el campo de instrucciones de los datos de inicio de sesión cuando vuelvas a enviar:
brokenFunctionality.template
La versión de Apple del mismo rechazo
Apple lo llama Guideline 2.1 — Performance — App Completeness, y es su motivo de rechazo más citado. Mismas causas de fondo, otra consola: la cuenta de demostración va en App Store Connect → tu app → Información de revisión de la app, con el interruptor «Requiere inicio de sesión» activado, más el campo Notas para todo lo que un desconocido no podría adivinar. Una diferencia importa mucho en la práctica: Apple normalmente te dice qué pantalla falló y adjunta una captura. Google te da una línea. Esa asimetría es la razón de que la tabla descodificadora de arriba tuviera que existir.
Los motivos de rechazo más habituales en la App Store
Qué podemos comprobar por ti, y qué no
Sube el .aab o el .apk que estás a punto de enviar y leemos su manifiesto. De las 24 comprobaciones de Android de la herramienta, 10 se ejecutan automáticamente, y cuatro apuntan directamente a causas de Broken Functionality:
- usesCleartextTraffic: una URL base http:// que funciona en tu máquina y queda bloqueada en silencio en una build de release en Android 9 o superior.
- android:debuggable: una build de depuración publicada por accidente, que de por sí ya es un rechazo inmediato.
- Actividad MAIN/LAUNCHER: no tener punto de entrada lanzable es, literalmente, «app doesn't load».
- targetSdkVersion y minSdkVersion: el desajuste que hay detrás de «app doesn't install» en un dispositivo de revisión.
Las otras 14 son las preguntas que ningún analizador puede responder por ti, y tres de ellas son exactamente esta política: si todas las funciones están operativas sin marcadores de posición ni enlaces rotos, si has probado en dispositivos reales y revisado Android vitals, y si la app hace algo real más allá de envolver una web.
Lo que no podemos hacer, sin rodeos: no ejecutamos tu app. No podemos decirte que tu backend está dormido, que tu cuenta de demostración caducó el martes pasado o que tu clave de Maps está atada al SHA-1 equivocado. Ninguna herramienta que analice un binario puede. Para eso está la pasada de 30 minutos.
Preguntas frecuentes
¿Qué significa «Your app contains content that isn't compliant with the Broken Functionality policy»?
Significa que el revisor de Google abrió tu app y falló, se congeló o nunca llegó a ser usable. Es un veredicto sobre el comportamiento, no una revisión de código. La línea corta que va debajo —por ejemplo «App installs, but doesn't load»— es el único diagnóstico que vas a tener, así que empieza por ahí.
Mi app funciona perfectamente. ¿Por qué dice Google que está rota?
Porque el revisor no está en tu dispositivo ni en tu red. Una pantalla de acceso sin credenciales de prueba, una API con lista blanca a la IP de tu oficina, una URL de staging en la build de release o un backend dormido producen todos una app que a él le falla y a ti te funciona. Nada de eso aparece en los informes de fallos.
¿Tengo que subir un .aab nuevo para arreglar un rechazo por Broken Functionality?
No siempre. Si la causa fueron unos datos de acceso ausentes o caducados, los actualizas en Política y programas → Contenido de la app → Datos de inicio de sesión y pulsas Enviar para revisión en la página Resumen de publicación: se reenvía la build existente. Si la causa está en la app, necesitas un nuevo código de versión.
¿El informe previo al lanzamiento detecta problemas de Broken Functionality?
En parte. La prueba Robo encuentra fallos y ANR en dispositivos reales, pero no puede iniciar sesión a través de un login en WebView ni manejar controles dibujados en OpenGL. Si tu app tiene login en WebView, el informe parecerá limpio cubriendo solo la pantalla de acceso. Mira la pestaña Capturas para ver hasta dónde llegó realmente el rastreador.
¿Puedo apelar un rechazo por Broken Functionality?
Sí: una apelación por cada medida de cumplimiento, con respuesta normalmente en unos 2 días laborables. Apela solo si has reproducido las condiciones del revisor en un dispositivo limpio y de verdad no has encontrado nada. Si no, arregla la causa, sube el código de versión y vuelve a enviar; es más rápido que perder la apelación.
¿Cuánto tarda la aprobación después de reenviar?
Google no garantiza plazos, y varía de un día a un par de semanas según la cuenta y el historial de infracciones. Planifica el reenvío como si fuera el último: un segundo rechazo por Broken Functionality en la misma app cuesta muchísimo más tiempo del que habría costado la pasada de diagnóstico de 30 minutos.
Fuentes
- Google Play — Funcionalidad, contenido y experiencia de usuario (texto de la política de Broken Functionality)
- Google Play — Requisitos para facilitar datos de inicio de sesión para la revisión
- Google Play — Facilitar información para la revisión de la app (Contenido de la app → Datos de inicio de sesión)
- Google Play — Usar un informe previo al lanzamiento para detectar problemas
- Android developers — ANR (el límite de 5 segundos para eventos de entrada)
- Android developers — Umbrales de mal comportamiento de Android vitals
- Google Play — Gestionar infracciones de las políticas y apelaciones
- Comunidad Android Builder — «Issue found: Violation of Broken Functionality policy» (el caso de la pausa de varios segundos)
Analiza tu build antes de enviar
Pasa tu .ipa o .apk por App Review Checker y detecta estos problemas en segundos.
Analizar una app