java.io.IOException: Cleartext HTTP traffic to [host] not permitted significa que Android rechazó una solicitud http:// sin cifrar conforme a la política efectiva de seguridad de red de la aplicación. Esto afecta con mayor frecuencia a Android 9 o posterior cuando la aplicación tiene como destino el nivel de API 28 o superior, incluidas las solicitudes realizadas mediante componentes HTTP de la plataforma y Media3 o ExoPlayer. La primera medida más segura es identificar el host bloqueado exacto o el origen de la redirección y trasladar esa solicitud a HTTPS si el endpoint lo admite; no habilites globalmente el tráfico sin cifrar antes de localizar el destino.
Qué significa “Cleartext HTTP Traffic Not Permitted”
El mismo fallo de política puede aparecer como java.io.IOException: Cleartext HTTP traffic to [host] not permitted, CLEARTEXT communication to [host] not permitted by network security policy o la forma abreviada Cleartext HTTP traffic not permitted. Media3 puede informar también el código relacionado ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED o CleartextNotPermittedException. La redacción visible puede variar según el componente o la biblioteca.
Estas firmas indican que la aplicación intentó establecer una conexión HTTP sin cifrar y que su política efectiva rechazó la solicitud. La documentación de Configuración de seguridad de red de Android establece que la compatibilidad con tráfico sin cifrar está deshabilitada de forma predeterminada para las aplicaciones con nivel de API de destino 28 o superior. El nivel de API de destino es relevante; que el dispositivo físico ejecute Android 9 o una versión posterior no demuestra por sí solo cómo está configurada la política de cada aplicación.
Esta guía se aplica cuando una URL directa, una redirección, una respuesta del backend, una lista de reproducción multimedia, un recurso de CDN, un componente de la plataforma o un SDK de terceros conduce a HTTP. No se aplica a SSLHandshakeException, CertPathValidatorException ni android.os.NetworkOnMainThreadException, que representan condiciones de fallo diferentes.
Identifica el endpoint HTTP que Android está bloqueando
Identifica el destino en tiempo de ejecución antes de cambiar la política de la aplicación. Es posible que la URL visible en el código fuente no sea la que Android acaba bloqueando.
- Anota el host mostrado en la excepción o en la salida de Logcat.
- Comprueba si la URL de la solicitud original comienza con
http://. - Comprueba si una solicitud HTTPS inicial redirige a HTTP.
- Comprueba si una respuesta del backend, una lista de reproducción multimedia o una CDN proporciona la URL de un recurso HTTP.
- Utiliza el seguimiento de pila para identificar si la solicitud procede de un componente de la plataforma, Media3 o ExoPlayer, WebView, o una biblioteca o un SDK de terceros.
La reproducción multimedia puede fallar aunque la URL inicial parezca correcta porque una lista de reproducción o un recurso referenciado conduce a HTTP. La guía oficial de solución de problemas de tráfico sin cifrar en Media3 identifica como causa de esta familia de errores una URL HTTP utilizada bajo una política que prohíbe el tráfico sin cifrar.
Las URL HTTP directas, las redirecciones a HTTP y los recursos HTTP devueltos por un backend requieren la misma decisión inicial: determinar si ese destino exacto puede utilizar HTTPS. No crees una excepción de dominio hasta conocer el host real en tiempo de ejecución.
Solución 1: Migra la solicitud que falla a HTTPS
Cuándo se aplica: Utiliza esta solución cuando controles el servidor o endpoint multimedia, o puedas cambiar el origen de la URL, y el recurso esté disponible mediante HTTPS.
Requisitos previos:
- Controlas el endpoint o puedes cambiar el origen que proporciona su URL.
- El recurso está disponible mediante HTTPS.
- Cambia el origen de la URL de
http://ahttps://. - Actualiza las redirecciones para que permanezcan en HTTPS.
- Vuelve a probar la solicitud exacta o la ruta de reproducción que fallaba.
Resultado esperado: Si todos los recursos de la ruta probada permanecen en HTTPS, Android ya no debería rechazar esa operación por tratarse de tráfico sin cifrar. Una redirección posterior, una entrada de una lista de reproducción o una URL HTTP proporcionada por el backend todavía puede activar el error y debe comprobarse por separado.
Riesgo y reversión: Este es un cambio de configuración de riesgo bajo que no debería provocar pérdida de datos. Restaura la URL anterior únicamente si falla la implementación de HTTPS. No amplíes este paso a la solución de problemas de certificados no relacionados; los fallos de validación de certificados quedan fuera del alcance de este error.
Verifica el manifiesto combinado y la política de seguridad de red empaquetada
Cuándo se aplica: Utiliza esta solución de diagnóstico confirmada cuando el manifiesto de origen o la Configuración de seguridad de red parezca correcta, pero la compilación en ejecución siga bloqueando la solicitud.
Requisito previo: Debes poder inspeccionar el manifiesto combinado o los recursos empaquetados de la compilación afectada.
- Comprueba el manifiesto combinado, no solo el XML de origen.
- Confirma que el archivo
network_security_config.xmlempaquetado esté presente. - Verifica que el host de la solicitud coincida exactamente con el dominio permitido.
- Comprueba si una redirección o lista de reproducción apunta a HTTP.
- Vuelve a probar la variante de compilación de destino.
Resultado esperado: La inspección debería revelar si la aplicación compilada contiene la referencia prevista a android:networkSecurityConfig y la política empaquetada, y si esa política cubre el host realmente bloqueado. También puede mostrar que interviene otra variante de compilación o un recurso HTTP posterior.
Riesgo y reversión: Este es un proceso de inspección de riesgo bajo, sin riesgo de pérdida de datos y sin necesidad de reversión. No supongas que un cambio en un archivo de origen está activo hasta comprobar el resultado combinado y empaquetado.
Solución 2: Permite el tráfico sin cifrar únicamente para el dominio necesario
Cuándo se aplica: Utiliza una excepción específica por dominio solo cuando HTTP sea inevitable y hayas identificado el destino exacto que lo requiere.
Requisitos previos:
- La aplicación tiene como destino el nivel de API 24 o superior.
- Puedes identificar el host o subdominio exacto.
- Aceptas que el tráfico HTTP sin cifrar puede exponer los datos transmitidos a interceptación o modificación.
- Añade un XML de Configuración de seguridad de red.
- Configura un
domain-configconcleartextTrafficPermitted="true"únicamente para el host necesario. - Mantén
includeSubdomainsen false salvo que todos los subdominios necesiten realmente HTTP. - Referencia el XML mediante
android:networkSecurityConfig. - Vuelve a probar el endpoint bloqueado.
Resultado esperado: El destino especificado podrá utilizar HTTP mientras que los demás destinos seguirán sujetos a las restricciones de tráfico sin cifrar de la aplicación. El resultado depende de que el dominio configurado coincida con el host real en tiempo de ejecución, incluido cualquier destino de una redirección o recurso multimedia.
Riesgo y reversión: Este es un cambio de seguridad de riesgo medio que no debería provocar pérdida de datos. El tráfico sin cifrar sigue siendo vulnerable aunque el destino sea de confianza. Elimina el domain-config o migra el endpoint a HTTPS para revertir la excepción. No amplíes la configuración a dominios no relacionados ni habilites includeSubdomains únicamente para hacer que una solicitud funcione.
Comportamiento según el nivel de API y alternativa android:usesCleartextTraffic
En el intervalo de destino relevante, el tráfico sin cifrar está bloqueado de forma predeterminada a partir del nivel de API 28. La Configuración de seguridad de red permite controlar la política de tráfico sin cifrar desde el nivel de API 24. Para el nivel de API 23 y anteriores, las indicaciones proporcionadas para estas versiones de Android requieren android:usesCleartextTraffic además de una estrategia de configuración de red.
Una Configuración de seguridad de red puede anular android:usesCleartextTraffic en Android N y versiones posteriores. Más importante aún, la documentación oficial del atributo de aplicación usesCleartextTraffic indica que el atributo se ignora en las aplicaciones con nivel de API de destino 38 o superior. Por tanto, no constituye un reemplazo compatible a futuro para la Configuración de seguridad de red.
Cuándo se aplica la alternativa amplia: Utiliza android:usesCleartextTraffic="true" únicamente por compatibilidad temporal o cuando deba permitirse todo el tráfico sin cifrar en un intervalo de destino anterior y todavía no exista una opción más limitada por dominio.
Requisitos previos:
- Entiendes que esta configuración debilita ampliamente la seguridad del transporte.
- Todavía no dispones de una opción más limitada y específica por dominio.
- Establece
android:usesCleartextTraffic="true"en el elemento de la aplicación. - Verifica el manifiesto combinado en el APK o AAB compilado.
- Si también existe una configuración de red, confirma que la aplicación siga bloqueando los destinos no previstos.
- Planifica la migración a la Configuración de seguridad de red o a HTTPS.
Resultado esperado: En los intervalos de destino donde se respete el atributo, la aplicación podrá realizar solicitudes sin cifrar salvo que una Configuración de seguridad de red efectiva imponga un comportamiento diferente. Esta alternativa no funcionará en aplicaciones con nivel de API de destino 38 o superior.
Riesgo y reversión: Esta es una alternativa de seguridad de riesgo alto porque puede permitir tráfico sin cifrar en toda la aplicación. No borra los datos de la aplicación, pero puede exponer los datos transmitidos a interceptación o modificación. Para revertirla, vuelve a establecer el atributo en false y elimina las dependencias HTTP.
Comprueba localhost, 10.0.2.2, direcciones IP numéricas, redirecciones y URL multimedia
El desarrollo local y las URL de recursos generadas requieren una verificación específica de la aplicación. Si el destino es localhost, una dirección de bucle invertido, 10.0.2.2 o una dirección IP numérica, confirma el host real en tiempo de ejecución y el entorno de compilación previsto antes de cambiar la política. Los informes relacionados con estos destinos son señales de diagnóstico útiles, pero no determinan cómo coincidirá la configuración de una aplicación concreta con su host.
- Confirma si el destino se utiliza únicamente durante el desarrollo.
- Comprueba si la misma política de tráfico sin cifrar se incluye involuntariamente en una compilación de producción.
- Inspecciona las redirecciones, listas de reproducción multimedia, recursos de CDN y URL proporcionadas por el backend para localizar destinos HTTP.
- Antes de extraer conclusiones específicas sobre un componente, identifica si el error procede de HttpURLConnection, OkHttp, WebView, MediaPlayer, DownloadManager, Media3, ExoPlayer o un SDK de terceros.
- Prueba manualmente el host y la variante de compilación afectados en lugar de suponer que una excepción de dominio coincide con todos los destinos locales o numéricos.
No habilites tráfico sin cifrar en toda la aplicación de producción únicamente para admitir un servidor de desarrollo. Si HTTP es temporalmente inevitable, limita cualquier excepción confirmada al destino necesario y verifica que no sea más amplia de lo previsto.
Confirma que el error exacto se haya resuelto sin ampliar el acceso HTTP sin cifrar
- Vuelve a probar la solicitud, la cadena de redirecciones o la ruta de reproducción exactas que produjeron originalmente el error.
- Prueba la variante de compilación de destino afectada en lugar de suponer que una variante representa todas las compilaciones.
- Después de cambiar una política, vuelve a comprobar el manifiesto combinado y la Configuración de seguridad de red empaquetada.
- Si utilizaste una excepción de dominio, confirma que solo se permita el destino necesario y que los demás destinos HTTP continúen bloqueados.
- Antes de interpretar el comportamiento del manifiesto, registra si la compilación tiene como destino el nivel de API 28 o superior y el nivel de API 38 o superior.
La operación original debería completarse sin la firma de rechazo de tráfico sin cifrar, mientras la aplicación conserva la política más limitada posible. Un cambio en un archivo de origen no confirma por sí solo que el problema esté resuelto. Si el error persiste, vuelve a comprobar el host en tiempo de ejecución, la cadena de redirecciones, los recursos de la lista de reproducción, la configuración empaquetada y la biblioteca de origen en lugar de ampliar la excepción.

