Historia

Mars Climate Orbiter: el fallo vivía en el hueco de en medio

El 23 de septiembre de 1999 se perdió una sonda de unos 125 millones de dólares porque un software entregaba impulsos en libra-fuerza segundo y el que los leía esperaba newton segundo. La especificación lo decía; lo que faltó fue alguien que comprobara que se cumplía.

Hoy, 23 de septiembre, se cumplen 27 años de la pérdida del Mars Climate Orbiter. La sonda llegó a Marte el 23 de septiembre de 1999, ejecutó la maniobra de inserción orbital, se ocultó detrás del planeta y no volvió a dar señal. El coste del orbitador se cifra habitualmente en unos 125 millones de dólares; los 327,6 millones que también se citan son otra cosa: la misión completa —orbitador y módulo de aterrizaje—, con 193,1 de desarrollo, 91,7 de lanzamiento y 42,8 de operaciones.

La causa se resume en una frase que se ha repetido tanto que ha perdido el filo: un equipo trabajaba en unidades imperiales y el otro en métricas.

Como resumen es correcto. Como explicación es inútil, porque deja al lector con la sensación de que aquello fue un despiste tonto que a él no le puede pasar. Y sí puede.

La sonda Mars Climate Orbiter en una sala de ensayos, con sus paneles solares plegados

La Mars Climate Orbiter durante los ensayos acústicos previos al lanzamiento, en 1998. Foto: NASA, dominio público, vía Wikimedia Commons.

Qué ocurrió exactamente

Durante el vuelo, la sonda ejecutaba periódicamente pequeñas maniobras para descargar las ruedas de reacción que mantenían su orientación. Los propulsores empleados producían también un pequeño cambio de velocidad, y ese impulso debía incorporarse al modelo de trayectoria para saber dónde estaba realmente la nave.

Y aquí conviene precisar la unidad, porque casi todas las versiones de esta historia la cuentan mal. No son fuerzas: son impulsos, fuerza por tiempo. El programa SM_FORCES, software de tierra del fabricante, entregaba esos impulsos en libra-fuerza segundo (lbf·s). El sistema de navegación que los consumía esperaba newton segundo (N·s).

Una libra-fuerza segundo son unos 4,45 newton segundo. Así que cada dato entraba en el modelo con una magnitud unas cuatro veces y media menor de la que correspondía.

Y aquí toca ser justo, porque la versión bonita —«nadie hacía nada mal»— no se sostiene: la especificación de la interfaz exigía unidades métricas y el software las entregó en unidades inglesas. Hubo un incumplimiento concreto, y la investigación encontró además fallos de comunicación, verificación, navegación y gestión. La lección que me interesa es que ese contrato no se verificó nunca: existía en un documento, y un documento sin pruebas ni dueño operativo no comprueba nada.

El efecto se acumuló durante nueve meses de vuelo. Al llegar, la nave pasó a unos 57 km de altura en vez de los 226 previstos. La junta de investigación concluyó que a esa altura o bien se destruyó en la atmósfera o bien salió despedida a una órbita heliocéntrica; nadie lo vio, así que sigue siendo lo uno o lo otro.

Un número no es un dato

La lección técnica es de una simpleza incómoda: un número sin unidad no es información, es una cifra.

Y esto no ocurre en las agencias espaciales. Ocurre en tu base de datos, ahora mismo:

  • Una columna duracion. ¿Segundos, milisegundos o minutos? Depende de quién insertó y de cuándo.
  • Un campo precio. ¿Con impuestos o sin ellos? ¿En qué moneda? ¿En euros o en céntimos?
  • Un peso. ¿Kilos o gramos? Lo sabe el que hizo el formulario, y ya no trabaja aquí.
  • Una fecha guardada como texto. ¿Zona horaria? ¿UTC o local? ¿Y cuando cambia la hora en octubre?
  • Un timeout de 30. Treinta de qué.

Cada uno de esos campos funciona perfectamente mientras solo lo toque quien conoce la convención. Falla el día que aparece una integración nueva, un informe nuevo o una persona nueva. Es decir: queda expuesto a fallar más tarde.

Las medidas preventivas son sencillas; corregirlo cuando el dato ya circula por varios sistemas puede no serlo:

  1. La unidad en el nombre. duracion_ms, precio_centimos_sin_iva, peso_gramos, timeout_segundos. Es feo y hace mucho más difícil equivocarse. Un nombre feo que no admite dos lecturas gana a un nombre elegante que las admite.
  2. Tipos que llevan la unidad dentro. Si tu lenguaje te deja modelar un Dinero o una Duracion en lugar de pasar enteros sueltos, el compilador hace de revisor gratis.
  3. Validación de rango en la frontera. Si un impulso o un precio llega cuatro veces y media fuera de lo esperable, hay que gritar. Un valor sintácticamente válido puede ser físicamente absurdo, y esa es una última barrera muy eficaz contra este tipo de fallo.

La interfaz es de todos y por tanto de nadie

Lo verdaderamente instructivo del caso no es la conversión. Es dónde estaba el fallo: en la frontera entre dos organizaciones.

Cada equipo tenía su especificación, sus revisiones y su gente competente. La documentación de la interfaz existía y decía lo que había que decir. Lo que no había era nadie que comprobara que se cumplía: qué formato llega de verdad, qué unidades, qué rangos, quién valida qué y qué pasa si algo no cuadra.

Esa figura falta en casi todos los proyectos donde participa más de un equipo:

  • La API que documentas tú y consume otro. Tu documentación dice lo que devuelve, no lo que significa.
  • El fichero que un proveedor deja cada noche en una carpeta, con un formato que se acordó en un correo de hace tres años.
  • El campo que un departamento rellena a mano y otro interpreta en un informe de dirección.
  • La integración que funciona porque los dos equipos hicieron la misma suposición razonable, hasta que uno de los dos la cambia por otra igual de razonable.

En todos esos sitios la pregunta útil es: ¿quién es el dueño del contrato? No de cada lado: del contrato. Y no basta con que la responsabilidad sea compartida sobre el papel: si no se traduce en una comprobación que alguien ejecuta, funciona como responsabilidad de nadie.

Las señales que sí hubo

El informe de investigación posterior dejó claro algo que suele omitirse cuando se cuenta la anécdota: no fue una sorpresa absoluta. A lo largo del vuelo hubo discrepancias en el comportamiento de la trayectoria que se detectaron y se comentaron, y el proceso para convertir esa inquietud en una revisión formal no llegó a activarse a tiempo.

Ese es el patrón, y se parece muchísimo a los 97 correos de Knight Capital: la información existía dentro de la organización. Lo que faltaba era el camino desde «esto me da mala espina» hasta «paramos y lo miramos».

En equipos pequeños ese camino es una conversación. En cuanto hay dos organizaciones, un calendario apretado y un coste percibido por levantar la mano, deja de existir salvo que alguien lo construya a propósito. Y lo que queda escrito de esas sospechas es, casi siempre, lo único que sobrevive al incidente.

La prueba para saber si el tuyo funciona es concreta: ¿cuándo fue la última vez que alguien paró algo por una sospecha que luego resultó infundada? Si nunca ha pasado, no significa que no haya sospechas. Significa que no se dicen.

Feliz aniversario, tristemente

Cuatro cosas para hoy:

  1. Abre el esquema de tu base de datos y busca las columnas numéricas sin unidad en el nombre. Localiza las tres peores y decide cómo hacer explícita su unidad. Puede ser un renombrado, una migración gradual o un campo nuevo; lo importante es eliminar la ambigüedad.
  2. Coge la última integración que montaste y escribe el contrato en un documento. Campos, unidades, rangos válidos, qué hacer con lo que llegue fuera de rango. Media página basta.
  3. Ponle nombre al dueño de ese contrato. Una persona.
  4. Añade una validación de rango en la entrada. No de formato: de plausibilidad.

(Y la próxima vez que alguien resuma esto como «se confundieron con las millas», corrígelo con cariño: no fue un despiste de alguien echando cuentas. Fue un formato incumplido que nadie comprobó, en la frontera entre dos sistemas, que es donde vive casi siempre.)

Preguntas frecuentes

¿Qué le ocurrió al Mars Climate Orbiter?

La sonda alcanzó Marte el 23 de septiembre de 1999 y ejecutó la maniobra de inserción orbital, tras la cual pasó por detrás del planeta y no volvió a establecer contacto. La reconstrucción posterior determinó que se aproximó a unos 57 kilómetros de altitud frente a los 226 previstos. La junta de investigación concluyó que, a esa altura, la nave se destruyó en la atmósfera o bien salió despedida hacia una órbita heliocéntrica, sin que pueda afirmarse cuál de las dos cosas ocurrió. El coste del orbitador se cifra habitualmente en torno a los 125 millones de dólares; los 327,6 millones que suelen citarse corresponden a la misión completa —orbitador y módulo de aterrizaje—, con 193,1 millones de desarrollo, 91,7 de lanzamiento y 42,8 de operaciones.

¿En qué consistió exactamente el error de unidades?

Las magnitudes implicadas son impulsos, no fuerzas. El programa SM_FORCES entregaba los impulsos de las maniobras de descarga de las ruedas de reacción expresados en libra-fuerza segundo (lbf·s), mientras que el software de navegación que los incorporaba al modelo de trayectoria esperaba recibirlos en newton segundo (N·s), conforme exigía la especificación de la interfaz. Dado que una libra-fuerza segundo equivale aproximadamente a 4,45 newton segundo, cada valor se integraba con una magnitud sensiblemente inferior a la real, y la desviación se acumuló durante los nueve meses de crucero interplanetario.

¿Por qué no basta con decir que alguien se equivocó de unidades?

Porque no fue un error de cálculo de una persona. Sí hubo un incumplimiento concreto —la especificación de la interfaz exigía unidades métricas y el software las entregó en unidades inglesas—, y la investigación identificó además deficiencias de comunicación entre equipos, de verificación, de navegación y de gestión del proyecto. La causa estructural es que ese contrato entre sistemas estaba documentado pero no se verificaba: una interfaz sin pruebas y sin responsable operativo sigue siendo frágil aunque su documentación sea correcta.

¿Cómo se previene este tipo de fallo en sistemas de información?

Mediante tres medidas complementarias. Incluir la unidad en el nombre de campos y columnas, de modo que no admitan dos lecturas posibles. Utilizar tipos de datos que encapsulen la magnitud y su unidad en lugar de transferir valores numéricos sin contexto, lo que permite que las herramientas de análisis detecten incompatibilidades. Y establecer validaciones de plausibilidad en los puntos de entrada, capaces de rechazar valores sintácticamente correctos pero incompatibles con el rango esperado.

¿Qué significa asignar un propietario al contrato de integración?

Significa designar a una persona responsable de la especificación que rige el intercambio entre dos sistemas, y no solo de cada uno de los extremos. Esa especificación debe recoger el formato, las unidades, los rangos admisibles, la periodicidad y el tratamiento previsto para los datos que no cumplan las condiciones. Cuando la responsabilidad se atribuye conjuntamente a ambos equipos sin concreción nominal, en la práctica no recae en ninguno.

Otras noticias

El blog, día a día

71 artículos publicados 24 mar 2026 — 23 mar 2027

¿Te ha resultado útil o quieres comentar algo?

Hablemos →