L'essentiel
  • Un overflow float64 vers int16 (valeur 40 000 dans un registre 16 bits = -32 768 en Ada) a détruit la fusée Ariane 5 en 37 secondes le 4 juin 1996.
  • Le code Ada incriminé avait été copié d'Ariane 4 sans retester dans le contexte plus rapide d'Ariane 5, où la vitesse horizontale dépassait les limites du type de destination.
  • mypy avec --strict détecte les incompatibilités de types numériques avant l'exécution et aurait signalé ce bug à la compilation.
  • NumPy et Cython exposent Python aux mêmes overflows que C ; les types natifs Python (int, float) sont eux illimités.
  • 370 millions de dollars et 10 ans de développement détruits en 37 secondes parce que personne n'avait revérifié les hypothèses du code hérité.

Lecture complète : 12 min

4 juin 1996. 37 secondes après le décollage, Ariane 5 explose en vol.

10 ans de développement. 370 millions de dollars. Partis en fumée littéralement, au-dessus de la forêt guyanaise. L’enquête conclut en quelques semaines : la cause, c’est une conversion de nombre décimal en entier sur une valeur trop grande pour le type de destination. Une ligne de code Ada héritée d’Ariane 4, copiée sans vérification, qui a planté le système de navigation.

Ce bug a 30 ans. Il est encore pertinent aujourd’hui parce que la même erreur se produit en Python, en JavaScript, en Go, et dans tout langage où les types numériques ont des limites. Et parce que des outils comme mypy permettent de la détecter avant l’exécution. Avant l’explosion.

Voici l’histoire, le code, et ce que tu peux mettre en place dès aujourd’hui.


Ce qui s’est passé le 4 juin 1996

Ariane 5 est le successeur d’Ariane 4. Pour gagner du temps, les équipes ont réutilisé une partie du logiciel de navigation d’Ariane 4. Logique sur le papier : pourquoi réécrire ce qui marche ?

Le problème : Ariane 5 était beaucoup plus puissante qu’Ariane 4. Sa trajectoire initiale produisait une vitesse horizontale bien plus élevée. Cette valeur de vitesse horizontale, calculée en nombre décimal 64 bits, était convertie en entier 16 bits pour être transmise au système de référence inertielle.

Sur Ariane 4, cette valeur ne dépassait jamais la capacité d’un entier 16 bits. Un entier 16 bits signé peut stocker des valeurs entre -32 768 et 32 767. Sur Ariane 5, la valeur dépassait 32 767. La conversion a échoué. Le système de navigation a reçu des données corrompues, interprétées comme un code d’erreur de diagnostic. Il s’est mis en sécurité et a coupé les moteurs.

37 secondes après le décollage, sans propulsion, la fusée a dévié de sa trajectoire. Le système de destruction automatique a pris le relais.

Le rapport de la commission d’enquête est public depuis 1996. Il est d’une clarté froide : le code n’avait pas été retesté dans le contexte d’Ariane 5. La protection contre l’overflow avait été retirée sur certaines variables pour des raisons de performance, sans analyse des risques.

Schéma de la conversion float64 vers int16 ayant causé la perte d'Ariane 5


Qu’est-ce qu’un overflow entier ?

Un overflow entier se produit quand une valeur numérique dépasse la capacité maximale du type qui est censé la stocker. En Ada, en C, en C++, les entiers ont des tailles fixes. Tenter de stocker 40 000 dans un entier 16 bits signé ne produit pas d’erreur visible : le nombre est simplement tronqué, et le résultat est un nombre incohérent qui va corrompre silencieusement tes calculs.

En C, un int16_t qui dépasse 32 767 revient à -32 768. C’est le comportement défini par la norme pour les types entiers signés.

#include <stdint.h>
#include <stdio.h>

int main() {
    int16_t vitesse = 32767;
    vitesse += 1;
    printf("%d\n", vitesse);  // Affiche -32768
    return 0;
}

Ariane 5 n’a pas planté sur un message d’erreur explicite. Elle a planté parce qu’un nombre de 40 000 est devenu un nombre négatif, interprété comme un code d’erreur système.


Reproduire le bug Ariane 5 en Python

Python standard n’a pas ce problème : ses entiers sont de précision arbitraire. Ils ne débordent jamais.

x = 32767
x += 1
print(x)  # Affiche 32768, pas -32768

Mais dès que tu utilises NumPy, qui est partout dans le code scientifique et de data science, le comportement change radicalement.

import numpy as np

vitesse_horizontale = np.int16(32767)
print(vitesse_horizontale + np.int16(1))
# Affiche -32768

# Simulation simplifiée du bug Ariane 5
def convertir_vitesse_navigation(vitesse_float64: np.float64) -> np.int16:
    # Aucune vérification des limites, exactement comme dans le code original
    return np.int16(vitesse_float64)

vitesse_ariane5 = np.float64(40000.0)
resultat = convertir_vitesse_navigation(vitesse_ariane5)
print(f"Vitesse convertie : {resultat}")
# Affiche : Vitesse convertie : -25536
# Un nombre absurde, interprété comme erreur système

Ce nombre, -25536, c’est ce que le système de navigation d’Ariane 5 a reçu à la place d’une vitesse mesurée. Il ne pouvait pas faire autrement que de paniquer.

La correction est triviale. Deux lignes :

import numpy as np

def convertir_vitesse_navigation_safe(vitesse_float64: np.float64) -> np.int16:
    INT16_MAX = np.iinfo(np.int16).max  # 32767
    INT16_MIN = np.iinfo(np.int16).min  # -32768
    
    if vitesse_float64 > INT16_MAX or vitesse_float64 < INT16_MIN:
        raise OverflowError(
            f"Vitesse {vitesse_float64} hors limites int16 [{INT16_MIN}, {INT16_MAX}]"
        )
    
    return np.int16(vitesse_float64)

# Test
try:
    resultat = convertir_vitesse_navigation_safe(np.float64(40000.0))
except OverflowError as e:
    print(f"Erreur détectée avant conversion : {e}")
    # Comportement de sécurité ici : log, alerte, valeur par défaut

Sur Ariane 5, lever une exception aurait stoppé proprement le calcul. Le système de navigation aurait reçu un signal d’erreur explicite plutôt qu’une valeur corrompue silencieuse. Peut-être qu’il aurait pu continuer en mode dégradé.

Tu builds des outils marketing ou SaaS ? Si tes textes fonctionnent autant que ton code, passe-les au Diagnostic de Performance sur copyboost.io pour voir ce qui coince.


Comment détecter un overflow avec mypy

mypy est un vérificateur de types statique pour Python. Il analyse ton code sans l’exécuter et signale les incohérences de types avant que tu ne déploies quoi que ce soit. Il ne détecte pas directement les overflows numériques, mais il détecte les conversions de types dangereuses et les fonctions qui reçoivent des types inattendus.

Voici comment l’utiliser sur ce type de bug.

pip install mypy

Exemple de code sans annotations de type :

# navigation.py
import numpy as np

def convertir_vitesse(v):
    return np.int16(v)

vitesse = 40000.0
nav_value = convertir_vitesse(vitesse)

mypy ne peut pas déduire grand chose ici. Maintenant avec des annotations :

# navigation_typed.py
import numpy as np
from numpy.typing import NDArray

def convertir_vitesse(v: np.float64) -> np.int16:
    return np.int16(v)

vitesse: np.float64 = np.float64(40000.0)
nav_value: np.int16 = convertir_vitesse(vitesse)
mypy navigation_typed.py --strict

mypy ne lèvera pas d’erreur ici parce que la conversion est techniquement valide en termes de types. Mais en combinant mypy avec une fonction de validation typée et un plugin comme beartype ou des assertions explicites, tu crées une défense en profondeur :

from typing import assert_never
import numpy as np

def convertir_vitesse_validee(v: np.float64) -> np.int16:
    limite = np.iinfo(np.int16)
    assert limite.min <= v <= limite.max, (
        f"Overflow détecté : {v} hors de [{limite.min}, {limite.max}]"
    )
    return np.int16(v)

mypy vérifiera que v est bien de type np.float64 à l’appel. Si tu passes un int Python classique par erreur, mypy te le signale avant l’exécution.

J’utilise mypy sur Copyboost depuis que j’ai eu un bug subtil de type sur les données Supabase. Ca m’a économisé plusieurs cycles de debug. J’en parle dans mon article sur les 5 erreurs Python sur VPS qui m’ont coûté des heures.

La config mypy minimale que j’utilise :

# mypy.ini
[mypy]
python_version = 3.11
strict = true
warn_return_any = true
warn_unused_ignores = true

Tests unitaires : la deuxième ligne de défense

mypy analyse les types. Les tests unitaires vérifient le comportement aux limites. Les deux sont complémentaires.

Pour le bug Ariane 5, le test unitaire qui aurait tout changé :

import pytest
import numpy as np
from navigation import convertir_vitesse_navigation_safe

def test_conversion_dans_les_limites():
    assert convertir_vitesse_navigation_safe(np.float64(1000.0)) == np.int16(1000)

def test_conversion_limite_haute():
    assert convertir_vitesse_navigation_safe(np.float64(32767.0)) == np.int16(32767)

def test_conversion_limite_basse():
    assert convertir_vitesse_navigation_safe(np.float64(-32768.0)) == np.int16(-32768)

def test_overflow_positif_leve_exception():
    with pytest.raises(OverflowError):
        convertir_vitesse_navigation_safe(np.float64(32768.0))

def test_overflow_negatif_leve_exception():
    with pytest.raises(OverflowError):
        convertir_vitesse_navigation_safe(np.float64(-32769.0))

def test_valeur_ariane5_leve_exception():
    # La valeur réelle qui a détruit Ariane 5
    with pytest.raises(OverflowError):
        convertir_vitesse_navigation_safe(np.float64(40000.0))
pytest test_navigation.py -v

Output d&#x27;un test pytest qui passe avec la fonction de conversion sécurisée

Six tests. Trois minutes à écrire. Des décennies de leçon condensées.

Le rapport d’enquête sur Ariane 5 note explicitement que le code Ada original d’Ariane 4 n’avait pas été retesté dans les conditions de vol d’Ariane 5. Les tests existants validaient le comportement normal, pas les cas limites. C’est exactement ce que test_valeur_ariane5_leve_exception aurait capturé.

Quand tu réutilises du code existant dans un nouveau contexte, les anciens tests ne suffisent plus. Le nouveau contexte crée de nouvelles hypothèses. Ces hypothèses doivent être testées.


Questions fréquentes

Qu’est-ce que le bug Ariane 5 exactement ?

Le 4 juin 1996, la fusée Ariane 5 a explosé 37 secondes après son décollage à cause d’une erreur de conversion numérique dans son logiciel de navigation. Une valeur de vitesse horizontale, représentée en nombre décimal 64 bits, a été convertie en entier 16 bits sans vérification des limites. La valeur dépassait la capacité du type entier, ce qui a produit un nombre corrompu interprété comme une erreur système fatale.

Un overflow entier peut-il se produire en Python ?

Python natif ne produit pas d’overflow sur ses entiers car ils sont de taille arbitraire. Mais dès que tu utilises NumPy, Pandas ou tout code qui manipule des tableaux typés, les entiers ont des limites fixes comme en C. Un np.int16 déborde exactement comme un int16_t en C. Le bug Ariane 5 est totalement reproductible avec NumPy.

Comment mypy aide à prévenir les bugs de type numérique ?

mypy vérifie statiquement que les types passés à tes fonctions correspondent aux types attendus. Il ne détecte pas les overflows numériques directement, mais il détecte les conversions de types implicites et les fonctions mal utilisées avant l’exécution. Combiné à des assertions de validation aux limites dans le code, il forme une défense solide contre ce type de bug.

Pourquoi le code d’Ariane 4 a-t-il été réutilisé sans tests supplémentaires ?

Selon le rapport de la commission d’enquête de 1996, la décision de réutiliser ce module venait d’une analyse de risque incorrecte. L’équipe a estimé que le module était “correct” parce qu’il fonctionnait sur Ariane 4. Elle n’a pas vérifié si les valeurs d’entrée possibles sur Ariane 5 restaient dans les mêmes plages. C’est un biais classique : confondre “le code fonctionne” avec “le code est correct dans ce nouveau contexte”.

Quel est le coût total du bug Ariane 5 ?

La destruction de la fusée et de sa charge utile représentait environ 370 millions de dollars. C’était le vol inaugural d’Ariane 5, ce qui signifie que ce bug a aussi retardé le programme de plusieurs années. Le coût indirect en délais, en réputation et en reconfiguration du programme est bien plus difficile à chiffrer.


Ce que tout dev devrait retenir de ce crash

Le code qui marchait hier ne marche pas forcément dans un nouveau contexte. C’est la leçon numéro un d’Ariane 5.

La leçon numéro deux : les limites de types sont des contrats implicites. Quand tu convertis un float en int, tu fais le pari que la valeur tiendra dans la destination. Ce pari doit être vérifié explicitement, pas assumé.

Trois choses à faire dès cette semaine :

  1. Installe mypy sur ton projet et active le mode strict
  2. Ajoute une validation aux limites sur toute conversion numérique qui traite des données externes ou calculées
  3. Ecris les tests de cas limites avant d’écrire le code principal, au moins sur les fonctions numériques critiques

Si tu réutilises du code existant dans un nouveau contexte, recommence les tests depuis zéro. “Ca marchait avant” n’est pas un argument de sécurité.

Teste aussi tes textes de landing page avec le même niveau de rigueur. Lance un audit gratuit sur copyboost.io pour voir ce que ton lecteur ressent vraiment.

Dernière mise à jour : mai 2026

Cet article fait partie de la série 10 bugs informatiques qui ont tué, crashé et coûté des milliards.