Une erreur No space left on device alors que df -h affiche 40 % d’espace libre n’est pas une contradiction : ce n’est jamais l’espace disque qui manque, ce sont les inodes, une ressource entièrement distincte et tout aussi finie, jamais visible dans la sortie par défaut de df.
Ce qu’un inode est réellement
Chaque fichier sur un système de fichiers de type ext4 (et la plupart de ses équivalents) occupe un inode, une structure qui stocke ses métadonnées (propriétaire, permissions, emplacement des blocs de données), indépendamment de sa taille. Un système de fichiers formaté avec un nombre fixe d’inodes, décidé au moment du formatage, ne peut jamais créer plus de fichiers que ce nombre, même si l’espace disque en blocs reste largement disponible.
# df -h ne montre que l'espace en blocs,
# jamais le nombre d'inodes disponibles
df -h /
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 50G 20G 28G 40% /
La commande qui révèle le vrai problème
df -i affiche l’utilisation des inodes exactement comme df -h affiche l’utilisation de l’espace, une vérification systématiquement omise parce que rarement le premier réflexe face à une erreur No space left on device.
# Le vrai indicateur à vérifier en premier
# face à une erreur "No space left on device"
df -i /
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 3276800 3276800 0 100% /
Un IUse% à 100 % avec un Use% en blocs largement en dessous confirme sans ambiguïté que le problème est l’épuisement des inodes, pas l’espace disque.
Le scénario classique : des millions de petits fichiers
L’épuisement d’inodes survient presque toujours de la même façon : un processus crée un très grand nombre de petits fichiers (des fichiers de session PHP jamais nettoyés, une file de mail en échec qui accumule des messages, un cache d’application qui écrit un fichier par requête sans jamais purger). Chaque fichier, même vide, consomme un inode entier : un million de fichiers de quelques octets épuise les inodes bien avant d’épuiser l’espace disque.
# Compter les inodes utilisés par répertoire,
# pour localiser où les fichiers s'accumulent
for dir in /var/* /tmp/*; do
echo "$dir: $(find "$dir" -xdev | wc -l)"
done
Pourquoi augmenter la taille du disque ne résout rien
Ajouter de l’espace disque à une partition n’ajoute jamais d’inodes supplémentaires à un système de fichiers déjà formaté : le nombre d’inodes est fixé une fois, au formatage, en fonction de la taille prévue à ce moment-là et d’une estimation de la taille moyenne des fichiers. Un disque agrandi après coup, sans reformatage, garde exactement le même nombre d’inodes qu’avant, ce qui signifie qu’un problème d’épuisement d’inodes revient rapidement même après avoir ajouté de l’espace.
# Reformater avec un ratio d'inodes plus généreux,
# la seule vraie solution durable si le volume de
# petits fichiers est structurel, pas ponctuel
mkfs.ext4 -N 10000000 /dev/sdX
À retenir
No space left on device avec df -h montrant de l’espace libre signale presque toujours un épuisement d’inodes, une ressource distincte de l’espace disque, fixée au formatage et invisible dans la commande df par défaut. df -i révèle immédiatement le vrai problème ; la cause la plus fréquente est un processus qui accumule un très grand nombre de petits fichiers sans jamais les nettoyer, la même logique de ressource kernel finie qui explique aussi l’épuisement de la table conntrack. Agrandir la partition ne change jamais le nombre d’inodes d’un système de fichiers déjà formaté, ce qui rend la purge des fichiers en excès (ou un reformatage avec un ratio d’inodes adapté) la seule vraie solution, un des pièges Linux classiques qui reste pertinent quel que soit le niveau d’abstraction de l’infrastructure au-dessus, y compris derrière une migration Kubernetes.