La web de una editorial llevaba años publicando a buen ritmo. Cientos de artículos, un feed RSS activo y sindicación a varios agregadores y newsletters externas. No era un sitio donde el feed existiese por inercia: era el canal principal de distribución. Cada entrada publicada llegaba a lectores, plataformas y boletines antes de que nadie la buscase en Google. El flujo llevaba funcionando sin interrupciones desde hacía mucho tiempo.
La migración al nuevo dominio estaba planificada. DNS, certificados, redirecciones del dominio antiguo al nuevo, cambio de dominio reflejado en la base de datos con un search & replace. El sitio cargaba bien bajo la nueva dirección, el panel respondía, las entradas se veían correctamente en el navegador. Todo parecía cerrado.
Pero a las 48 horas empezaron los avisos. Un agregador estaba duplicando entradas. Una newsletter mostraba artículos de hacía meses como si fuesen nuevos. Algunos lectores RSS enseñaban enlaces con el dominio antiguo en ciertos sitios y el nuevo en otros. No era un fallo visible en el navegador ni un problema de DNS. Era algo que solo se manifestaba a través del feed, como si el sitio estuviera contando dos historias distintas a quien lo leía desde fuera.

Operario: WordPin
Archivo del caso: El cambio de dominio y los GUID confusos
Empresa o negocio: Editorial con RSS activo y sindicación
Archivado en: Migraciones en WordPress
Nivel: Avanzado
Qué dejó de cuadrar tras el cambio de dominio
Lo primero que revisé fue el feed en bruto. Cargué la URL del RSS directamente en el navegador para ver el XML sin procesamiento externo. La estructura estaba limpia: elementos <item> bien formados, fechas correctas, títulos y descripciones coherentes. No había errores de sintaxis ni nodos rotos. Cualquier validador habría dicho que el feed era correcto.
Sin embargo, al comparar el feed con la lista de entradas que los agregadores estaban mostrando como nuevas, el patrón era claro: no eran entradas recién publicadas. Eran artículos antiguos, algunos de hacía más de un año, que de repente aparecían como contenido fresco. Y no todos. Solo un grupo concreto.
Abrí Google Search Console para comprobar si el rastreador estaba interpretando algo raro. No había errores de cobertura nuevos significativos, pero sí un ligero incremento en el número de URLs rastreadas del sitio respecto a semanas anteriores. Nada alarmante por sí solo, pero tampoco el comportamiento esperado para un sitio que no estaba publicando más contenido del habitual.
Entradas duplicadas, URLs cruzadas y un patrón irregular
La primera sospecha fue la caché del servidor. El sitio usaba Varnish como capa de caché, y era plausible que el feed estuviese sirviendo una versión cacheada con referencias al dominio anterior. Si la caché no se había purgado completamente tras la migración, los agregadores podían estar recibiendo un feed híbrido: parte nuevo dominio, parte antiguo. Lo comprobé directamente con un bypass:
curl -H "Cache-Control: no-cache" -s https://nuevodominio.com/feed/ | head -80El resultado mostraba el feed generado en tiempo real, sin caché. Y las inconsistencias seguían ahí. Las mismas entradas que los agregadores marcaban como nuevas aparecían también en este feed limpio. La caché no era la causa. Si lo hubiera sido, el bypass habría devuelto un feed consistente con el nuevo dominio.
La segunda hipótesis apuntaba a un search & replace incompleto en wp_options. Si siteurl o home seguían apuntando al dominio antiguo, WordPress podía estar generando URLs mixtas en el feed. Accedí a phpMyAdmin y ejecuté una consulta directa:
SELECT option_name, option_value
FROM wp_options
WHERE option_name IN ('siteurl', 'home');Ambos valores devolvían el nuevo dominio correctamente. No había rastro del antiguo en esas opciones. También revisé permalink_structure y las opciones de lectura del feed: todo coherente. Aquí había una pista que no estaba mirando bien.
Que un cambio de dominio deje residuos en wp_options es habitual cuando el proceso no cubre todas las tablas o no deserializa datos serializados. Pero en este caso, las opciones principales estaban limpias. Las URLs visibles en el navegador funcionaban bien. El problema solo se manifestaba en el canal de distribución externo: feeds, lectores RSS, agregadores. Algo más profundo estaba mezclando señales.
Revisé también si algún plugin de sindicación estaba generando su propio feed o alterando las URLs de salida. No había plugins de ese tipo activos. El feed lo generaba el propio WordPress, sin filtros adicionales. El sitio respondía bien en superficie, pero el feed contaba otra historia a quien lo leía desde fuera.
Lo que el feed estaba revelando
Volví al XML del feed, pero esta vez no miré los títulos, las fechas ni los enlaces principales. Me fijé en los elementos <guid>. Y ahí estaba la fractura.
En WordPress, cada entrada tiene un campo GUID en la tabla wp_posts. Es un identificador único global que los lectores RSS usan para distinguir una entrada de otra. No es una URL funcional: es una referencia permanente. Si un lector de feeds ve un GUID que no reconoce, interpreta esa entrada como contenido nuevo, independientemente de la fecha de publicación. Si el GUID cambia, la entrada vuelve a aparecer como si acabase de publicarse.
El cambio de dominio y lo que no debía tocarse
Al revisar la columna guid en wp_posts, apareció algo que no esperaba: los identificadores no eran uniformes. Algunas entradas conservaban el formato original con el dominio antiguo, mientras otras mostraban ya el nuevo. La mezcla no seguía ningún criterio aparente de fecha, categoría ni tipo de contenido. La migración había dejado una tabla con identificadores incoherentes, sin que fuera evidente en qué punto del proceso había ocurrido ni por qué solo parte de los GUID habían quedado alterados. Lo confirmé con una consulta directa en phpMyAdmin:
SELECT ID, post_title, guid
FROM wp_posts
WHERE post_status = 'publish'
AND post_type = 'post'
ORDER BY ID DESC
LIMIT 20;El resultado era exactamente lo que el feed estaba delatando: entradas con GUID que alternaban entre el dominio viejo y el nuevo sin lógica visible. Las entradas cuyo GUID no coincidía con el que los agregadores tenían registrado eran precisamente las que se estaban redistribuyendo como contenido nuevo. El lector RSS veía un identificador desconocido y las trataba como publicaciones recientes.
El problema no estaba en las URLs visibles del sitio. Estaba en los identificadores internos que el cambio de dominio nunca debería haber afectado. WordPress no usa los GUID para resolver rutas ni para mostrar contenido al usuario. Los usa exclusivamente como referencia para feeds y para evitar importaciones duplicadas. Alterar un GUID es como cambiar el número de serie de un artículo ya distribuido: todo el sistema externo que lo usaba como referencia deja de reconocerlo. Un error parcial suele ser más peligroso que una caída total, porque deja demasiadas cosas funcionando.
El impacto en la sindicación era directo. Cada entrada con GUID alterado volvía a entrar en el circuito de distribución como si fuese nueva. Las newsletters reenviaban artículos antiguos. Los agregadores los republicaban. Y algunos lectores RSS acumulaban duplicados sin forma de filtrarlos, porque el identificador que usaban para detectar repeticiones ya no coincidía con el que tenían en memoria.
Restaurar los identificadores sin romper lo que ya funcionaba
La primera tentación era lanzar una operación de sustitución sobre la columna guid en wp_posts: devolver todos los identificadores al formato original con el dominio antiguo y dejarlos como estaban antes de la migración. Parecía rápido. Pero tenía un riesgo serio.
Si se revertían todos los GUID al dominio antiguo, las entradas publicadas después del cambio de dominio también quedarían con un identificador que nunca existió bajo ese dominio. Esas entradas habían nacido ya bajo el nuevo, y sus GUID actuales eran legítimos. Reescribirlos habría provocado el efecto contrario: lectores RSS interpretando entradas realmente nuevas como contenido desconocido por segunda vez, generando otra ola de duplicados.
Corregir los registros sin arrastrar el problema al feed
La corrección tenía que ser quirúrgica. Solo debían restaurarse los GUID de las entradas que existían antes de la migración y cuyo identificador había quedado alterado. Las entradas publicadas después de la migración debían conservar su GUID actual, porque ese era su identificador legítimo desde el primer momento.
Usé la copia de seguridad previa a la migración para extraer los GUID originales. Crucé esa tabla con la tabla activa filtrando por ID y post_type = 'post', y generé una lista de los registros donde el GUID actual no coincidía con el original. Eran 347 entradas de un total de más de 1.200 publicadas.
Antes de tocar nada en producción, repliqué la operación en un entorno de staging. Restauré los GUID originales solo en esos 347 registros, regeneré el feed y lo pasé por el W3C Feed Validation Service. El feed validaba sin errores y, lo más importante, los elementos <guid> de las entradas antiguas volvían a mostrar su identificador original. Eso era exactamente lo que los lectores RSS esperaban encontrar.
Apliqué la corrección en producción y monitoricé el feed durante las siguientes 72 horas. Los agregadores dejaron de duplicar entradas. Las newsletters que tenían programadas redistribuciones automáticas no volvieron a mostrar artículos antiguos como nuevos. Revisé también Google Search Console para confirmar que no aparecían errores de cobertura nuevos ni incrementos anómalos en el rastreo de URLs del sitio.
WordPress necesita que los GUID sean estables. No son URLs funcionales, no afectan al enrutamiento, no participan en la resolución de permalinks. Pero son la pieza que sostiene la identidad de cada entrada fuera del sitio. Si quedan alterados tras un cambio de dominio, el daño no aparece en el navegador: aparece en cada sistema externo que confiaba en ellos.
En paralelo, revisé que las URLs reales del sitio — las que sí debían apuntar al nuevo dominio — estuviesen reforzadas correctamente. Comprobé las etiquetas canonical, las redirecciones 301 del dominio antiguo al nuevo y los sitemaps enviados a Search Console. Esas señales sí debían reflejar el nuevo dominio, y lo hacían. La diferencia era clara: las URLs son direcciones; los GUID son identidades. Cambiar una dirección es parte de una migración. Cambiar una identidad es destruir una referencia.

💡 Qué he aprendido
Este caso me recordó algo que doy por sabido pero que en la práctica se ignora más de lo que debería: no todo lo que parece una URL dentro de WordPress funciona como una URL. Los GUID tienen forma de enlace, pero no son enlaces. Son etiquetas. Y cuando una migración los toca sin distinguirlos de las URLs reales del sitio, el problema no estalla en el navegador sino en el ecosistema que depende del feed. Es un fallo silencioso, fácil de pasar por alto, porque el usuario no lo ve y el sitio sigue cargando con normalidad.
He aprendido a separar con más cuidado qué columnas deben actualizarse en un cambio de dominio y cuáles no deben tocarse bajo ningún concepto. Y a incluir siempre una validación del feed y una revisión de los GUID como parte del checklist de cualquier migración, no como paso opcional que se añade solo si hay problemas.
A veces el síntoma más revelador no está donde el usuario navega, sino donde las máquinas leen.
Cuaderno de WordPin
Forense WordPress
🧩 Notas técnicas
⬋⬋
Editorial con sindicación activa a agregadores y newsletters. Tras migrar al nuevo dominio, el sitio cargaba correctamente en el navegador, pero los feeds RSS empezaron a generar duplicados en los canales externos. El problema no se manifestaba en la navegación normal, sino exclusivamente en la distribución por feed.
La columna guid en wp_posts quedó con identificadores mixtos tras la migración: algunos apuntaban al dominio antiguo, otros al nuevo. Los lectores RSS no reconocían los GUID modificados y redistribuían esas entradas como contenido nuevo. La corrección requirió restaurar solo los GUID alterados usando la copia de seguridad previa, sin afectar a las entradas publicadas después de la migración.
🔎 Pistas detectadas
⬋⬋
- Agregadores mostrando artículos antiguos como publicaciones nuevas 48 horas después de la migración.
- Feed XML sintácticamente válido pero con elementos
<guid>inconsistentes entre entradas: parte con dominio antiguo, parte con el nuevo. - Valores de
siteurlyhomecorrectos enwp_options: el problema no estaba en las opciones principales. - Solo las entradas anteriores a la migración con GUID alterado generaban duplicados; las posteriores se comportaban con normalidad.
- El bypass de caché del servidor devolvía las mismas inconsistencias, descartando Varnish como causa.
🚫 Errores en WordPress detectados
⬋⬋
- Columna
guidenwp_postscon identificadores mixtos tras la migración, rompiendo la referencia permanente de cada entrada para lectores externos. - GUID tratados durante el proceso de migración como si fueran URLs funcionales del sitio, cuando su función es exclusivamente de identificación en feeds.
- Entradas existentes reinterpretadas como contenido nuevo por los agregadores RSS al no coincidir el GUID con el registrado previamente.
- Sindicación automática redistribuyendo artículos antiguos a newsletters y plataformas externas como publicaciones recientes.
- Ausencia de validación del feed y los GUID como parte del checklist de migración, impidiendo detectar el problema antes de que afectara a la distribución.
📘 Glosario de WordPress
⬋⬋
- GUID: identificador único global almacenado en
wp_posts; los lectores RSS lo usan para distinguir entradas, no es una URL funcional. - Sindicación RSS: distribución automática de contenido a agregadores y plataformas externas mediante un archivo de feed estructurado en XML.
- wp_posts: tabla principal de WordPress que almacena entradas, páginas, revisiones y tipos de contenido personalizados, incluyendo el campo
guid. - Feed XML: archivo estructurado que expone el contenido del sitio para que lectores y agregadores externos lo consuman y distribuyan automáticamente.
- Search & Replace en base de datos: operación habitual en migraciones de dominio que sustituye cadenas en tablas de WordPress; requiere control preciso sobre qué columnas se incluyen.
📏 Mini guía práctica
⬋⬋
- Excluye la columna
guidde cualquier operación de sustitución masiva durante una migración de dominio en WordPress. - Audita los GUID con una consulta SQL directa sobre
wp_postsantes y después de migrar para detectar identificadores alterados. - Valida el feed RSS con el W3C Feed Validation Service tras cada cambio de dominio y comprueba la coherencia de los elementos
<guid>. - Cruza el feed resultante con una copia del feed previo a la migración para identificar entradas que puedan aparecer como nuevas en los agregadores.
- Restaura únicamente los GUID alterados usando la copia de seguridad previa, preservando los identificadores legítimos de las entradas publicadas tras la migración.
Deja una respuesta
SEO desde cero y el cliente que lo desconocía · Serpion 000
La migración de staging a URLs antiguas · WordPin 004
Expedientes y Archivos