¿Imagen rota en otra web? Árbol de errores 403 y antihotlink (2026)
Pegas el enlace de una imagen en tu blog y en la vista previa local se ve perfecto. Lo publicas, y lo que ve la gente es un marco de icono roto. O peor: toda la posición de la imagen queda en blanco, sin nada.
Esta trampa la he pisado más de una vez. Una vez la lié en producción ayudando a mudar imágenes en el foro de un amigo: en local todo verde, tras publicar un tercio de las miniaturas de la portada rotas, y yo pensando que era la caché sin limpiar. Estuve depurando tres días hasta descubrir que ni siquiera era problema mío: el sitio origen de las imágenes tenía activado el antihotlink (hotlink protection), y cualquier petición que no viniera de su propio dominio la bloqueaba.
Desde la arquitectura, «la imagen no se muestra en otra web» son en realidad tres fallos completamente distintos mezclados en una sola frase. Para arreglarlo bien, el primer paso es distinguir cuál de los tres te ha tocado.
Primero distingue: 403, imagen rota y 200 en blanco son tres cosas
Mucha gente, en cuanto ve que la imagen falta, lo llama todo «imagen rota» y prueba a lo loco. Pero la causa raíz de estos tres síntomas es muy distinta, y su ruta de diagnóstico también.
| Síntoma | Código HTTP | Causa raíz más probable | Dirección del diagnóstico |
|---|---|---|---|
| Marco de icono roto (icono partido) | 403 / 404 | Antihotlink bloquea, o el enlace es erróneo | Comprueba Referer y URL correcta |
| Marco de icono roto (icono partido) | 200 pero no imagen | Recibes una página de error HTML, no un archivo de imagen | Comprueba Content-Type |
| Espacio en blanco (sin icono roto) | 200 | CSS tapa, o CSP bloquea la carga | Comprueba consola de DevTools y CSP |
| Icono girando y luego desaparece | Timeout / CORS | Política de dominio cruzado o timeout del servidor | Comprueba los detalles de la petición en Network |
Primero el código de estado, luego el Content-Type, y al final la pantalla. Este orden al revés te hace dar vueltas sin salida.
Mecánica de fondo: cómo funcionan el Referer y el antihotlink
Para entender por qué la imagen de otro sitio se bloquea, hay que saber qué hace el navegador a escondidas al cargar la imagen.
Cuando la web A usa <img src="https://B.com/photo.jpg"> para cargar la imagen del sitio B, la petición que emite el navegador lleva una cabecera Referer (sí, esta palabra está históricamente mal escrita, le falta una r, y así se ha quedado hasta hoy). Esa cabecera le dice a B: «esta imagen la pide una página del sitio A».
La mecánica es así: el servidor o la CDN de B, al recibir la petición, coge el dominio del Referer y lo compara con una lista blanca. La lógica es aproximadamente:
1. Referer vacío (abrir imagen directa, marcador) → según config, deja pasar o bloquea
2. Dominio del Referer en lista blanca → deja pasar
3. Dominio del Referer fuera de lista blanca → devuelve 403 Forbidden
Esto es el antihotlink. Su objetivo es simple: no quiere que otros aprovechen su ancho de banda gratis. Si embebes en tu sitio una imagen de B, cada vez que alguien visita tu página el gasto de tráfico se carga a la cuenta de B, y a B, claro, no le hace gracia.
Aquí hay un detalle que mucha gente desconoce: la Referrer-Policy por defecto de los navegadores modernos es strict-origin-when-cross-origin. En peticiones de dominio cruzado, solo envía el «dominio de origen» (por ejemplo https://a.com/), no la ruta completa. Así que el antihotlink obtiene el nombre de tu dominio, suficiente para compararlo con la lista blanca y suficiente para bloquearte. Por eso el antihotlink puede con el hotlink.
Por qué tu imagen se rompe en otro sitio: un árbol de errores
Despliega la mecánica de arriba y la causa raíz de la imagen rota se condensa en un árbol. Bájalo siguiendo las ramas.
Rama uno: ¿el código de estado es 403?
Si sí, el 90% es antihotlink. B ve que tu Referer no está en su lista blanca y rechaza directo. En este caso no puedes cambiar la config de B, la única solución es dejar de hacer hotlink de su imagen (la solución correcta, más abajo).
Rama dos: ¿el código es 200 pero la imagen sale rota?
Abre el contenido original de esa «imagen». Es muy probable que lo que recibes sea una página HTML: algunos sitios no devuelven 403, sino una página de aviso de «no hacer hotlink», con código de estado 200. El navegador interpreta el HTML como imagen y, claro, te lo parte. El Content-Type lo delata: una imagen normal es image/jpeg, image/png; la página de error es text/html.
Rama tres: ¿pegaste el «enlace de página» y no el «enlace directo de imagen»?
Esta es la trampa más común del novato. https://imgur.com/aBcDeFg es una página; https://i.imgur.com/aBcDeFg.jpg es el archivo de imagen en sí. Si cargas la primera con <img src>, recibes una página HTML entera, no una imagen. Un i. y una extensión de diferencia, y el resultado es del cielo a la tierra.
Rama cuatro: ¿la Referrer-Policy te ha perjudicado a ti mismo?
Una más oculta. Si tu página tiene Referrer-Policy: no-referrer, el navegador no envía Referer alguno al cargar la imagen. Algunas configs de antihotlink son «Referer vacío se bloquea siempre», así que tu propia configuración de privacidad te deja fuera. En la práctica, este caso suele aparecer en sitios muy preocupados por la privacidad que apagan del todo la meta referrer.
Manos a la obra: DevTools y curl, dos golpes para localizarlo
Fin de la teoría. ¿Cómo se comprueba en la práctica? Uso dos herramientas fijas y en cinco minutos localizo el 90% de las imágenes rotas.
Primer golpe: panel Network de DevTools
Abre las herramientas de desarrollador del navegador (F12), ve a Network, recarga la página y en el filtro escribe el nombre del archivo de imagen. Entra en esa petición y mira tres cosas:
- Status: ¿es 403, 404 o 200?
Content-Typede las Response Headers: ¿esimage/*otext/html?Refererde las Request Headers: ¿qué se envía de verdad, vacío o tu dominio?
Con estas tres, la causa raíz casi emerge sola.
Segundo golpe: controlar el Referer a mano con curl
DevTools ve el fenómeno, pero para verificar «si es o no antihotlink», curl es lo más directo. Puedes meter a mano cualquier Referer y ver cómo cambia la respuesta del servidor:
# Sin Referer (simula abrir la imagen directa)
curl -I "https://example.com/photo.jpg"
# Con un Referer que "finge venir del propio sitio origen"
curl -I -H "Referer: https://example.com/" "https://example.com/photo.jpg"
# Con un Referer que "viene de tu sitio externo"
curl -I -H "Referer: https://tu-blog.com/" "https://example.com/photo.jpg"
La lectura es intuitiva. Si el primero y el tercero devuelven 403 pero el segundo devuelve 200, enhorabuena: antihotlink confirmado. El servidor solo reconoce el Referer del propio sitio origen y bloquea el resto. Si los tres devuelven 200, entonces la imagen rota no tiene que ver con el antihotlink; vuelve a revisar tu URL o el CSP.
Mi costumbre en la práctica es lanzar los tres a la vez: contrastar resultados es mucho más claro que mirar uno solo. Por eso curl es más eficiente que pinchar a ciegas en el navegador.
Comportamiento antihotlink de alojamientos / CDN comunes
El carácter por defecto de cada servicio varía mucho. Abajo va lo que he observado estos años mudando imágenes; la config real de cada uno puede cambiar en cualquier momento, pero la tendencia general es esta.
| Tipo de servicio | ¿Antihotlink por defecto? | Comportamiento con Referer vacío | ¿Bueno para enlace externo? |
|---|---|---|---|
| Nginx / Apache propio | Según cómo lo configures | Suele dejar pasar | Según config |
| CDN empresarial (lista blanca) | Se puede activar o no | Configurable, pasa o bloquea | Sí, si lo configuras bien |
| Parte de los alojamientos gratis | Suele estar activado | Suele bloquear | Suele bloquearse |
| Dominio de imagen de redes sociales | Casi siempre activado | Casi siempre bloquea | No, ni lo intentes |
| Alojamiento orientado a compartir | Suele estar apagado | Deja pasar | Sí, ese es su sentido de existir |
Lo clave es la última fila. Las imágenes de las redes sociales (los dominios de CDN de esas redes) que copias son casi al 100% imposibles de enlazar fuera, porque su modelo de negocio es tenerte encerrado dentro. Querer llevarlas a otro sitio a pegar es callejón sin salida.
Y el alojamiento orientado a «compartir» tiene el antihotlink apagado por defecto: su sentido de existir es que tu imagen se cargue de forma estable desde otros sitios. No confundas estas dos categorías.
La trampa de la Referrer-Policy: hasta el navegador puede perjudicarte
Antes mencioné un caso oculto; aquí lo desarrollo, porque es el que más te hace depurar hasta dudar de tu cordura.
La Referrer-Policy es una cabecera que puede fijar la página (la parte que emite la petición). Decide cuánta información de Referer envía el navegador. Hay varios valores:
no-referrer: no envía nada.origin: solo envía el dominio de origen.strict-origin-when-cross-origin: en dominio cruzado solo el dominio, y al bajar a HTTP no envía (valor por defecto moderno).unsafe-url: envía hasta la ruta completa (no recomendado, filtra privacidad).
Aquí la contradicción. El antihotlink necesita el Referer para juzgar el origen, pero la política de privacidad anima a enviar poco o nada de Referer. Cuando un sitio, por privacidad, fija no-referrer, y va a cargar cualquier imagen con antihotlink de tipo «Referer vacío se bloquea siempre», se le rompen todas.
Una vez la lié en producción justo con esto: cierto sitio muy preocupado por la privacidad tenía no-referrer en todo el sitio, y todas las imágenes externas se rompieron. Yo pensaba que el alojamiento se había caído, y tras un buen rato descubrí que era mi propia meta la que estrangulaba el Referer. Esta trampa cuesta imaginarla, porque «reforzar la privacidad», ¿cómo iba a perjudicarme a mí mismo?
La forma correcta: no hagas hotlink de imágenes ajenas
Al final del diagnóstico llegas a una verdad cruda: mientras la imagen no la alojes tú, cualquier «imagen de otro sitio» puede desaparecer en un momento que no controlas. La otra parte cambia el antihotlink, cambia la URL, borra el archivo o cierra el sitio entero, y tu página se rompe con ella.
Solo hay dos formas realmente estables.
Primera: realoja la imagen en un sitio que tú controles. No embebas la URL de otro directamente. Descarga la imagen, súbela a tu propio espacio o a un alojamiento que permita enlace externo, y usa esa URL estable. Desde la arquitectura, este paso recupera la disponibilidad de tu página, del servidor de otro a tus propias manos: mientras el origen no lo controles tú, cualquier ajuste de antihotlink, cambio de estructura de URL o incluso caída total del sitio se reflejará como imagen rota en tu página, y sin aviso previo, normalmente te enteras cuando un lector lo reporta. Si ya tienes un lote de enlaces viejos dispersos por dominios ajenos que quieres mudar de una vez, escribí aparte un SOP completo de reemplazo por lotes de enlaces de imagen, que con un script escanea las URLs viejas de todo el sitio y las reemplaza de golpe, mucho más cómodo que a mano una a una. El origen que controlas es el origen estable.
Segunda: elige un alojamiento con el antihotlink apagado por defecto. Muchos alojamientos gratis, para ahorrar ancho de banda, bloquean el enlace externo, y al pegarlo en un foro o blog te lo rompen. Para enlace externo, elige un servicio que permita el enlace directo de forma explícita.
Este es también un principio que aplicamos al hacer lpic.cc: tras subir te da una URL directa estable de imagen, sin bloquear otros sitios por defecto, para que la pegues en un foro, un blog o Discord y se muestre con normalidad, sin convertirse de repente en un 403. Para imágenes privadas, puedes controlar quién las ve con protección con contraseña. Si quieres probar, sube gratis una imagen, pega el enlace en otra página y comprueba si aguanta.
Con franqueza, hay que decir los límites: el plan gratuito conserva la imagen 30 días, no es archivo permanente, y el servicio se sostiene con ingresos de publicidad. Para archivar a largo plazo o una biblioteca de imágenes comercial masiva, deberías evaluar un plan profesional de pago o montar tu propio almacenamiento con copias. La herramienta solo tiene sentido en el escenario correcto; esto lo aprendí a base de pisar la trampa.
Preguntas frecuentes (FAQ)
P: ¿Por qué el mismo enlace de imagen a mí me abre, pero al pegarlo en otro sitio se rompe?
Porque al «abrir la imagen directa» tu Referer está vacío o viene de un origen permitido, y el antihotlink deja pasar. Al pegarla en otro sitio, el Referer pasa a ser ese dominio externo, no está en la lista blanca y se bloquea con 403. La misma URL, distinto Referer, resultado totalmente distinto.
P: ¿El 403 y la imagen rota son lo mismo?
No. El 403 es un rechazo explícito del servidor (código 403); la imagen rota es solo la representación visual de que el navegador «no puede pintar la imagen». El 403 causa imagen rota, pero la imagen rota también puede venir de URL errónea, Content-Type erróneo, CSP bloqueando la carga u otras causas. Mira primero el código de estado para saber cuál es.
P: ¿Poner la página en Referrer-Policy: no-referrer sortea el antihotlink?
A veces sí, a veces es peor. Si el antihotlink de la otra parte es «Referer vacío deja pasar», no enviar Referer funciona. Pero si es «Referer vacío se bloquea siempre», se te rompen todas. Este truco no es fiable, no lo uses como solución.
P: Con un programa (Python / Node) también me da 403 al descargar, ¿qué hago?
Igual que el navegador: tu programa no lleva el Referer correcto. Prueba primero con curl qué Referer reconoce la otra parte y añade esa misma cabecera a tu petición HTTP. Pero ojo: sortear el antihotlink ajeno para descargar imágenes puede violar los términos de servicio de la otra parte; y si esas imágenes contienen datos personales, en la UE el RGPD también entra en juego. Actúa con criterio.
P: ¿Cómo juzgo rápido si un alojamiento permite enlace externo?
Sube una imagen de prueba, coge su URL directa y lanza curl -I -H "Referer: https://google.com/". Si devuelve 200, permite enlace externo; si devuelve 403, tiene antihotlink, no lo uses para pegar fuera. Se verifica en treinta segundos.
References
- MDN Web Docs — Referrer-Policy header (fecha de acceso: 2026-06-26, explica los valores de policy y el comportamiento por defecto moderno
strict-origin-when-cross-origin) - AWS Security Blog — How to help prevent hotlinking using referer checking, AWS WAF, and Amazon CloudFront (fecha de acceso: 2026-06-26, mecanismo de comprobación de Referer a nivel de CDN)
- Alibaba Cloud CDN — Configure a Referer whitelist or blacklist to enable hotlink protection (fecha de acceso: 2026-06-26, lógica de dejar pasar / bloquear el Referer vacío)
- KeyCDN Support — Create a Zone Referrer (Hotlink Protection) (fecha de acceso: 2026-06-26, config de lista blanca antihotlink en CDN)
- ProxiesAPI — Fixing 403 Forbidden Errors for Image Requests in Code (fecha de acceso: 2026-06-26, 403 al descargar imágenes por código y diferencia de cabecera Referer)
- Patchstack — How To Prevent Image Hotlinking in WordPress (fecha de acceso: 2026-06-26, reglas antihotlink con .htaccess mod_rewrite)
Escrito por
Harvey ZhangCo-fundador & CTO
Ingeniero backend convertido en arquitecto, ofrece análisis técnico profundo sobre infraestructuras de alojamiento de imágenes.