Error de WordPress "No tienes permiso de subida": cómo solucionarlo
Resumen: el error proviene de tu servidor WordPress, no de la app de iPhone, el navegador ni el script que realiza la petición. Las dos causas más habituales son: (1) el usuario detrás de tu Application Password no tiene la capacidad upload_files, o (2) un plugin de seguridad o WAF está bloqueando /wp-json/wp/v2/media antes de que WordPress evalúe la petición. Asciende al usuario a Autor (o cualquier rol que incluya upload_files), o exime el endpoint de medios de la regla del firewall infractora, y las subidas funcionarán inmediatamente.
Verificado con WordPress 6.7 el 2 de junio de 2026.
Diagnóstico rápido: qué te dice la respuesta
Antes de cambiar nada, fíjate en la respuesta HTTP que recibe tu cliente. Cada combinación de código de estado y cuerpo de error apunta a una causa raíz distinta.
| Estado HTTP | Código de error | Causa probable | Primer paso |
|---|---|---|---|
| 403 | rest_cannot_create | El rol del usuario no tiene upload_files | Cambia el rol a Autor o superior (ver Causa raíz 1) |
| 401 | rest_invalid_authentication | Application Password incorrecta o revocada | Regenera la Application Password (ver Causa raíz 4) |
| 403 | página HTML, sin JSON | Un plugin de seguridad o WAF bloqueó la petición | Revisa el registro de eventos de Wordfence / iThemes / Cloudflare |
| 503 / timeout | (sin cuerpo) | El WAF o un limitador de tasa cortó la conexión | Inspecciona los registros de Cloudflare o del firewall de origen |
| 200 | página HTML, no JSON | La REST API de WP está desactivada por un plugin | Desactiva "Disable REST API" o equivalente |
Cómo llega realmente el error a tu cliente
Cuando un cliente sube una foto a WordPress, realiza una petición POST a /wp-json/wp/v2/media. La petición lleva una cabecera Authorization con tu nombre de usuario y una Application Password, un token que generas en Usuarios -> Perfil -> Contraseñas de aplicación, una funcionalidad del núcleo de WordPress desde la versión 5.6 (guía oficial de integración).
El núcleo de WordPress ejecuta entonces una comprobación de permisos antes de aceptar el archivo. La lógica relevante en WP_REST_Attachments_Controller::create_item_permissions_check() es:
if ( ! current_user_can( 'upload_files' ) ) {
return new WP_Error(
'rest_cannot_create',
__( 'Sorry, you are not allowed to upload media on this site.' ),
array( 'status' => rest_authorization_required_code() )
);
} Si el usuario detrás de la Application Password no tiene la capacidad upload_files, WordPress devuelve HTTP 403 con un cuerpo JSON que contiene "code": "rest_cannot_create". Tu cliente recibe esa respuesta y la muestra como "No tienes permiso de subida".
Esto significa que el mensaje es literal: WordPress te está diciendo que el usuario no tiene permiso para subir. El siguiente paso es averiguar por qué. La lista completa de capacidades por rol está documentada en la página oficial de Roles y Capacidades de WordPress.
Causa raíz 1: el rol del usuario no tiene upload_files
Esta es la causa más frecuente que observamos en los casos de soporte de SnapPress. WordPress tiene cinco roles por defecto, y solo algunos pueden subir medios:
| Rol | ¿Puede subir medios? |
|---|---|
| Administrador | Sí |
| Editor | Sí |
| Autor | Sí |
| Colaborador | No |
| Suscriptor | No |
Si tu Application Password pertenece a un Colaborador o Suscriptor, cada intento de subida fallará con el error de permiso, aunque la autenticación tenga éxito (la contraseña en sí es válida; simplemente no aporta suficiente acceso).
Cómo comprobar el rol
- Inicia sesión en tu administración de WordPress en
https://tu-sitio.example/wp-admin/. - Abre Usuarios -> Todos los usuarios.
- Encuentra el usuario cuya Application Password pusiste en la app cliente.
- Mira la columna Rol.
Si el rol es Colaborador, Suscriptor o cualquier rol personalizado que no incluya upload_files, ahí está tu problema.
Cómo solucionarlo (mínimo privilegio primero)
La solución más segura es ascender al usuario a Autor. Autor es el rol mínimo por defecto que incluye upload_files, además de la capacidad de crear y publicar las entradas del propio usuario. No puede gestionar otros usuarios, plugins ni ajustes, por lo que es la opción recomendada cuando solo se requiere el flujo de subida.
Asciende a Editor si el usuario también necesita editar y publicar entradas de otros autores, o a Administrador solo cuando el usuario realmente necesite el control total del sitio (por ejemplo, un sitio de un único propietario que gestionas tú mismo). Tras cambiar el rol, genera una nueva Application Password en el usuario ahora correcto y actualiza la app cliente. La contraseña nueva es recomendable pero no estrictamente necesaria; elimina la hipótesis de "credencial obsoleta".
¿Y si el rol es personalizado?
Si tu sitio usa un plugin de roles como Members o User Role Editor, el rol con nombre puede no coincidir con los predeterminados. Abre el editor de roles, busca el rol asignado a tu usuario y confirma que la casilla upload_files está activada. Guarda y vuelve a intentarlo. Los roles personalizados son también donde se ocultan la mayoría de regresiones de permisos; si las subidas funcionaban y dejaron de hacerlo silenciosamente tras una actualización de plugin, este es el punto por donde empezar. Para sitios multiusuario, el enfoque más limpio es un rol personalizado dedicado con upload_files más las capacidades mínimas de publicación que realmente necesites.
Causa raíz 2: un plugin de seguridad bloquea la REST API
Si tu rol de usuario ya incluye upload_files y las subidas siguen fallando, el siguiente sospechoso es un plugin de seguridad que intercepta la petición a la REST API antes de que el núcleo de WordPress la vea. Los infractores habituales:
- Wordfence: las reglas del firewall pueden coincidir con cabeceras Authorization inusuales; el Rate Limiting puede estrangular el tráfico REST.
- iThemes Security / Solid Security: las opciones de endurecimiento de la REST API pueden bloquear
/wp-json/wp/v2/*desde cualquier cosa que no sea una sesión de navegador con login. - Disable REST API: el plugin que literalmente se llama así bloquea todos los endpoints REST por defecto; debes añadir
/wp/v2/mediaa la lista blanca para que las subidas desde apps funcionen. - SecuPress, Shield Security y plugins similares tienen ajustes equivalentes.
Cuando uno de estos bloquea la petición, el cliente ve el mismo síntoma de "sin permiso de subida" porque el plugin devuelve un 403 parecido al propio error de WordPress. La diferencia es que la comprobación current_user_can() del núcleo nunca se ejecuta.
Detalles de Wordfence
Vale la pena revisar dos ajustes. Abre Wordfence -> All Options -> Firewall Options:
- Brute Force Protection: ajustes de bloqueo agresivos pueden vetar una Application Password tras un único reintento.
- Rate Limiting: los umbrales de "If anyone's requests exceed..." se aplican también al tráfico REST. Una app móvil que reintenta subidas fallidas puede dispararlos.
Si sospechas de Wordfence, abre Wordfence -> Tools -> Live Traffic y lanza una subida desde el cliente. Si la petición es bloqueada, la razón aparece en la entrada del registro con la regla que se activó. La referencia completa del firewall está en wordfence.com/help/firewall/.
Detalles de iThemes Security / Solid Security
Solid Security ha movido el endurecimiento de la REST API entre versiones. En versiones recientes, busca en Security -> Settings -> Advanced -> WordPress Tweaks la opción de la REST API (versiones anteriores la colocaban en Tools). Los dos estados que te importan son:
- Default (REST API activada): lo que las subidas desde app necesitan.
- Restricted: limita los endpoints REST a sesiones de navegador con login; las peticiones con Application Password pueden fallar aquí.
Cambia a Default si puedes, o añade explícitamente /wp/v2/media a la lista blanca. La etiqueta exacta puede variar según la versión; consulta la documentación de Solid Security para tu versión.
Cómo diagnosticarlo
Desactiva los plugins sospechosos de uno en uno y reintenta la subida entre cada uno. El plugin cuya desactivación hace que las subidas tengan éxito es el culpable. Una vez identificado, encuentra el ajuste específico que bloquea la REST API y exime /wp-json/wp/v2/media de él. Todos los plugins de la lista anterior admiten exenciones por endpoint de alguna forma, aunque las rutas del menú varían según la versión.
Causa raíz 3: un WAF está bloqueando la petición
Si tu sitio está detrás de un firewall de aplicaciones web (Cloudflare WAF, Sucuri, AWS WAF, BunkerWeb), el WAF puede rechazar la petición de subida antes de que llegue siquiera a tu servidor WordPress. Cloudflare en particular tiene reglas gestionadas de WAF que atacan cuerpos POST multipart grandes y combinaciones inusuales de Content-Type, ambas usadas en una subida de medios. Consulta la documentación del WAF de Cloudflare para el catálogo de reglas.
Los síntomas varían, pero normalmente obtienes uno de estos:
- HTTP 403 con una página de error de Cloudflare en el cuerpo de la respuesta.
- HTTP 503 o un timeout, sin cuerpo de error.
- HTTP 200 con una respuesta HTML en vez de JSON.
Solución específica y acotada para Cloudflare
No desactives en bloque las reglas gestionadas de Cloudflare. En su lugar, identifica la regla concreta que se disparó:
- Abre el panel de Cloudflare y ve a Security -> Events (antes Firewall Events).
- Lanza una subida que falle desde tu cliente.
- Filtra los eventos por host o por la URI
/wp-json/wp/v2/media. La regla bloqueadora aparece con su ID de ruleset y su ID de regla. - Crea una regla personalizada en Security -> WAF -> Custom Rules que omita solo esa regla gestionada concreta para el endpoint de subida:
(http.request.uri.path eq "/wp-json/wp/v2/media") and (http.request.method eq "POST") Configura la acción de la regla como "Skip" dirigida a la regla / ruleset específico que identificaste, no a todos los desafíos gestionados. Coloca la regla por encima de cualquier regla "Block" en prioridad. Esto mantiene la protección activa para el resto de /wp-json/ mientras permite que pasen las subidas de medios legítimas.
Causa raíz 4: fallo de autenticación o Application Password revocada
Las Application Passwords no tienen una expiración integrada; una vez emitidas, siguen siendo válidas hasta que se revocan manualmente. Por eso el síntoma aquí suele ser HTTP 401 con rest_invalid_authentication, no el error 403 de permiso. Pero vale la pena comprobarlo cuando nada más encaja:
- Abre administración de WordPress -> Usuarios -> Perfil -> Contraseñas de aplicación.
- Confirma que la contraseña que registraste en la app cliente sigue listada.
- Si fue eliminada (manualmente, por un plugin de seguridad o por un evento de cambio de contraseña), genera una nueva y actualiza el cliente.
- Confirma que tu sitio es accesible por HTTPS. WordPress elimina la cabecera Authorization en HTTP plano por seguridad; un desajuste http-a-https puede producir 401 intermitentes.
- Confirma que ningún plugin de seguridad o código personalizado haya desactivado las Application Passwords mediante el filtro
wp_is_application_passwords_available.
Algunos plugins de seguridad revocan automáticamente las Application Passwords en ciertos eventos (cambios de contraseña, cambios de rol, actividad sospechosa). Si tu rol cambió hace poco, eso por sí solo puede haber revocado las contraseñas existentes. Regenerarla es una solución de un minuto.
Confirmar la solución desde la línea de comandos
Una vez aplicada una solución, puedes verificar que las subidas funcionan sin involucrar la app cliente en absoluto. Desde cualquier máquina con curl, ejecuta:
curl -u 'your-username:your-application-password' \
-X POST \
-H 'Content-Disposition: attachment; filename=test.jpg' \
-H 'Content-Type: image/jpeg' \
--data-binary @test.jpg \
https://your-site.example/wp-json/wp/v2/media Una subida correcta devuelve HTTP 201 y un cuerpo JSON que incluye el id, source_url y media_details del nuevo elemento de medios. Cualquier otra cosa apunta de nuevo a la tabla de diagnóstico al inicio de este artículo, y el cuerpo de la respuesta normalmente te dice qué fila aplica.
Si no puedes ejecutar curl, la misma prueba puede hacerse desde Postman o cualquier cliente HTTP que admita autenticación Basic y datos de formulario multipart. El endpoint, las credenciales y la respuesta esperada son idénticos.
Por qué una app móvil no puede arreglar esto por ti
Es tentador suponer que un fallo de subida tiene que estar en la app, porque la app es la parte visible de la cadena. Pero la REST API de WordPress es el guardián autoritativo de lo que cualquier cliente (navegador, app iOS, Zapier, línea de comandos) tiene permitido hacer. El trabajo de la app es enviar una petición bien formada con credenciales válidas y mostrar la respuesta. Si WordPress dice "sin permiso de subida", cambiar la app no puede cambiar la respuesta. La solución tiene que ocurrir en el lado de WordPress: rol, ajustes de plugins, reglas de WAF o Application Password.
Esto es por diseño y es una fortaleza del modelo REST API. Las mismas comprobaciones protegen tu sitio tanto si alguien usa una app de móvil, un cliente de escritorio o escribe un script personalizado.
Lista de verificación resumen
- Lee el código de estado HTTP y el código de error de la respuesta real. Compáralos con la tabla de diagnóstico al inicio.
- Comprueba el rol de usuario de WordPress. Debe incluir
upload_files(Autor o superior entre los predeterminados). - Si el rol es correcto, desactiva los plugins de seguridad de uno en uno y reintenta las subidas.
- Si ningún plugin es la causa, revisa el registro de eventos de tu WAF; añade una excepción de regla acotada para
/wp-json/wp/v2/mediasolo para la regla concreta que se disparó. - Confirma que la Application Password sigue listada en el perfil del usuario y que tu sitio está en HTTPS; regenera si es necesario.
- Verifica de extremo a extremo con curl antes de volver a la app cliente.
Seguir este orden resuelve la mayoría de los reportes de "sin permiso de subida" que vemos de los usuarios de SnapPress. El mensaje de error está haciendo su trabajo; solo necesita el contexto adecuado para actuar.
Preguntas frecuentes
- ¿Por qué WordPress devuelve "No tienes permiso de subida" a mi app de iPhone?
- El endpoint de la REST API
/wp-json/wp/v2/mediarequiere que el usuario de WordPress tenga la capacidadupload_files. Los roles Suscriptor y Colaborador no la tienen. Si tu app de iPhone se autentica como un usuario con uno de esos roles, cada intento de subida devuelve HTTP 403 conrest_cannot_createcomo código de error. Ascender al usuario a Autor (o cualquier rol que incluyaupload_files) lo resuelve. - Soy el administrador del sitio y aún así obtengo "sin permiso de subida". ¿Qué está pasando?
- Cuando el rol del usuario es correcto, la siguiente causa probable es un plugin de seguridad o regla de WAF que bloquea la REST API. Wordfence, iThemes Security, Solid Security y los plugins "Disable REST API" tienen ajustes que pueden rechazar tráfico REST que no sea de navegador. Las reglas de Cloudflare WAF que apuntan a
/wp-json/tienen el mismo efecto. Usa el registro de eventos de tu firewall para encontrar la regla bloqueadora concreta y exime solo esa regla para/wp-json/wp/v2/media. - ¿La Application Password de WordPress otorga el mismo rol que el usuario al que pertenece?
- Sí. Las Application Passwords se emiten por usuario, y cualquier petición autenticada con una se ejecuta como ese usuario con sus capacidades exactas. Si el usuario subyacente es un Suscriptor, la Application Password no puede subir, aunque se generara correctamente. Las Application Passwords no tienen una expiración integrada; siguen siendo válidas hasta que se revoquen manualmente.
- ¿Cómo confirmo la capacidad upload_files desde una terminal?
- Ejecuta curl con
-u nombre-de-usuario:application-passwordy POST a/wp-json/wp/v2/mediacon una pequeña imagen de prueba. HTTP 201 con un cuerpo JSON que contenga el nuevo ID de medio significa que las subidas funcionan. HTTP 403 con códigorest_cannot_createsignifica que el rol no tieneupload_files. HTTP 401 conrest_invalid_authenticationsignifica que la Application Password es incorrecta o está revocada. HTTP 403 desde un cuerpo de respuesta no proveniente de WordPress (página HTML de error, desafío de Cloudflare) significa que un filtro previo está bloqueando la petición antes de que WordPress la vea. - ¿No sería mejor ascender al usuario directamente a Administrador?
- Solo como último recurso, y solo para sitios que controlas plenamente. El principio de mínimo privilegio dice que debes dar al usuario el rol más pequeño que conceda
upload_files, que es Autor. Reserva Administrador para cuentas que realmente necesiten gestionar ajustes, plugins u otros usuarios. Un rol personalizado dedicado con soloupload_filesmás capacidades de publicación es aún más seguro para sitios compartidos.