Impossible de créer le dossier.
En anglais : Could not create directory.
Réponse rapide
PHP n’a pas le droit d’écrire dans wp-content (ou le disque est plein). Alignez le propriétaire des fichiers sur l’utilisateur de PHP-FPM et appliquez 755 aux dossiers et 644 aux fichiers, puis relancez l’installation.
Vous installez un thème, vous mettez à jour une extension ou le cœur, et l’opération s’arrête sur « Impossible de créer le dossier. », souvent précédé de « La mise à jour a échoué : » ou de « L’installation de l’extension a échoué. ». Dans d’autres cas, WordPress ne dit rien de tel mais réclame des identifiants FTP dans un écran « Informations de connexion ». Les deux symptômes ont la même origine : WordPress n’arrive pas à écrire dans ses propres dossiers. L’erreur apparaît dans l’administration, jamais sur le site public.
Le site continue de fonctionner, rien n’est cassé, mais plus aucune installation ni mise à jour automatique ne passe tant que les droits ne sont pas corrigés. Voici comment trouver le dossier fautif et le réparer, avec ou sans accès à l’administration.
Ce que signifie cette erreur
Pour installer ou mettre à jour quoi que ce soit, WordPress passe par une couche d’abstraction du système de fichiers, WP_Filesystem. Il télécharge l’archive ZIP, la décompresse dans wp-content/upgrade/, puis copie les fichiers à leur place. Le texte « Impossible de créer le dossier. » vient d’un échec de mkdir() à l’une de ces étapes : décompression de l’archive (wp-admin/includes/file.php), copie d’un dossier (copy_dir()), déplacement (move_dir()) ou création du dossier de destination par WP_Upgrader (wp-admin/includes/class-wp-upgrader.php).
Le mode d’écriture est choisi par get_filesystem_method(). Si la constante FS_METHOD n’est pas définie, WordPress essaie de créer un fichier de test dans wp-content et compare son propriétaire à celui des fichiers du cœur : s’ils sont identiques, il utilise le mode direct. Sinon, il bascule sur FTP ou SSH et demande des identifiants. Les dossiers créés reçoivent les droits FS_CHMOD_DIR, calculés par défaut à partir de ceux de la racine du site (au minimum 755).
Autrement dit, l’erreur n’indique pas qu’un dossier est « interdit » à vous : elle signale que le compte système sous lequel PHP s’exécute ne peut pas écrire à cet endroit, ou que l’écriture échoue pour une autre raison (disque plein, restriction PHP, sécurité du système).
Diagnostic rapide
| Symptôme / constat | Cause probable | À vérifier |
|---|---|---|
| WordPress demande des identifiants FTP | Propriétaire des fichiers différent de l’utilisateur de PHP | ls -l sur wp-content, utilisateur PHP-FPM |
L’erreur ne touche qu’un dossier (upgrade, plugins, themes) | Droits ou propriétaire incohérents sur ce dossier | stat et namei -l sur le chemin |
| Les droits semblent corrects, l’erreur persiste | Disque ou quota plein, manque d’inodes | df -h et df -i |
| L’erreur apparaît après un changement d’hébergeur ou de serveur | Utilisateur PHP différent, open_basedir, SELinux | Pool PHP-FPM, open_basedir, getenforce |
| Le site tourne dans un conteneur ou un déploiement immuable | Système de fichiers en lecture seule par conception | Montage du volume wp-content |
Les causes les plus fréquentes
- Un propriétaire de fichiers différent de l’utilisateur de PHP : les fichiers appartiennent à l’utilisateur SFTP ou à
root, tandis que PHP-FPM s’exécute sous un autre compte (par exemplewww-data). - Des droits trop stricts sur
wp-content,wp-content/upgrade,pluginsouthemes(par exemple 555 ou 644 sur un dossier). - Un disque, un quota ou un nombre d’inodes saturé.
- Une restriction PHP ou système :
open_basedir, SELinux ou AppArmor, attribut immuable sur le dossier. - Un site migré ou restauré dont les fichiers gardent le propriétaire de l’ancien serveur.
- Un hébergement ou un conteneur où
wp-contentest volontairement en lecture seule.
Solutions pas à pas
1. Identifier l’utilisateur de PHP et le propriétaire des fichiers
Il faut comparer deux choses : le compte qui exécute PHP et le propriétaire des dossiers. Depuis SSH :
ps -eo user,comm | grep -E "php-fpm|apache2|httpd" | sort -u
stat -c '%U:%G %a %n' wp-content wp-content/upgrade wp-content/plugins wp-content/themes
namei -l /var/www/monsite/wp-content/upgrade
namei -l affiche les droits de chaque dossier du chemin : un seul maillon sans droit de passage suffit à tout bloquer. Pour tester l’écriture avec le compte de PHP (remplacez www-data par le vôtre) :
sudo -u www-data mkdir wp-content/upgrade/test-ecriture && sudo -u www-data rmdir wp-content/upgrade/test-ecriture
Si la commande échoue, le problème est confirmé. L’écran Outils > Santé du site signale aussi, dans l’onglet Statut, si le dossier de sauvegarde temporaire des mises à jour (wp-content/upgrade-temp-backup) est accessible en écriture. Notre article sur les permissions de fichiers WordPress détaille la relation entre propriétaire, groupe et utilisateur PHP.
2. Corriger le propriétaire et les droits
C’est la solution la plus propre, et elle règle aussi le basculement vers FTP. Faites une sauvegarde des fichiers avant toute modification massive. Placez-vous à la racine du site, puis alignez le propriétaire sur l’utilisateur de PHP et normalisez les droits :
chown -R www-data:www-data /var/www/monsite
find /var/www/monsite -type d -exec chmod 755 {} \;
find /var/www/monsite -type f -exec chmod 644 {} \;
Remplacez www-data et le chemin par vos valeurs. Sur un hébergement mutualisé, le propriétaire est en général déjà le compte de l’hébergement : réglez simplement les droits des dossiers à 755 depuis le gestionnaire de fichiers ou votre client SFTP. Évitez 777, qui ouvre l’écriture à tous les comptes du serveur. Si vous déployez vos fichiers en tant qu’un autre utilisateur, partagez plutôt un groupe commun avec chmod g+w sur wp-content.
3. Libérer de l’espace disque
Si les droits sont corrects, vérifiez la place disponible :
df -h /var/www
df -i /var/www
Un disque à 100 %, ou un nombre d’inodes épuisé, produit exactement la même erreur. L’article sur le disque plein sur un serveur WordPress explique comment repérer ce qui consomme la place (sauvegardes, journaux, caches, médias).
4. Vérifier les restrictions PHP et système
Contrôlez que open_basedir, s’il est défini, inclut le dossier du site et le dossier temporaire :
php -i | grep -E "open_basedir|upload_tmp_dir"
wp eval 'echo ini_get("open_basedir");'
Sur un système avec SELinux (RHEL, AlmaLinux, Rocky), getenforce indique l’état, et ausearch -m avc -ts recent liste les refus récents ; le dossier du site doit porter un contexte autorisant l’écriture par le serveur web (par exemple httpd_sys_rw_content_t). Vérifiez enfin qu’un attribut immuable ne protège pas le dossier (lsattr -d wp-content). Si WordPress télécharge dans un dossier temporaire inaccessible, vous pouvez en imposer un dans wp-config.php :
define( 'WP_TEMP_DIR', ABSPATH . 'wp-content/temp' );
Créez le dossier et donnez-lui les droits d’écriture pour l’utilisateur de PHP.
5. Forcer le mode d’écriture avec FS_METHOD (si vous maîtrisez le serveur)
Si PHP peut réellement écrire dans les dossiers mais que WordPress ne le détecte pas (cas typique : propriétaire des fichiers différent de celui des fichiers créés par PHP, mais groupe commun avec droit d’écriture), vous pouvez imposer le mode direct dans wp-config.php, avant la ligne « That’s all, stop editing! » :
define( 'FS_METHOD', 'direct' );
Cette constante court-circuite la vérification de propriétaire : n’en faites usage que si vous avez confirmé à l’étape 1 que l’écriture fonctionne, car en cas de doute l’erreur reviendra. À l’inverse, pour passer volontairement par FTP, les valeurs possibles sont direct, ssh2, ftpext et ftpsockets, avec les constantes de connexion correspondantes :
define( 'FS_METHOD', 'ftpext' );
define( 'FTP_HOST', 'ftp.exemple.fr' );
define( 'FTP_USER', 'utilisateur-ftp' );
define( 'FTP_PASS', 'mot-de-passe' );
define( 'FTP_SSL', true );
Ne stockez un mot de passe FTP en clair que si vous protégez wp-config.php ; le mode direct avec des droits corrects reste préférable. L’article sur l’API Filesystem de WordPress et son mode FTP détaille la logique de détection, et celui sur WP_Filesystem plutôt que file_put_contents intéressera les développeurs d’extensions.
6. Installer ou mettre à jour sans passer par l’administration
En attendant de régler les droits, vous pouvez contourner le problème. Avec WP-CLI, lancé sous le compte de PHP :
sudo -u www-data wp plugin update --all
sudo -u www-data wp theme install /chemin/vers/montheme.zip
Ou envoyez le dossier décompressé par SFTP dans wp-content/plugins ou wp-content/themes. Si l’échec a interrompu une mise à jour, consultez la fiche mise à jour échouée, et, si WordPress affiche un verrou, la fiche autre mise à jour en cours.
Prévenir l’erreur
- Déployez et administrez le site avec un seul compte système cohérent avec l’utilisateur de PHP-FPM, ou avec un groupe partagé et des droits de groupe corrects.
- Après une migration ou une restauration, réappliquez propriétaire et droits sur tout le site.
- Surveillez l’espace disque et les inodes, y compris sur les environnements de préproduction.
- Si vous interdisez volontairement l’écriture en production (conteneur, déploiement immuable), désactivez les mises à jour depuis l’administration et mettez à jour via votre pipeline.
- Ne contournez jamais le problème par
chmod 777: c’est une faille de sécurité, pas un correctif.
FAQ
Pourquoi WordPress me demande-t-il des identifiants FTP ?
Parce que le test d’écriture a échoué : le propriétaire des fichiers créés par PHP n’est pas celui des fichiers de WordPress, donc le mode direct est écarté. Corrigez le propriétaire, ou, à défaut, renseignez FS_METHOD en connaissance de cause.
Faut-il passer les dossiers en 777 ?
Non. Cela donne le droit d’écrire à tous les comptes du serveur et expose le site. Utilisez 755 pour les dossiers et 644 pour les fichiers, avec le bon propriétaire.
Où définir FS_METHOD ?
Dans wp-config.php, avant la ligne « That’s all, stop editing! ». Les valeurs acceptées sont direct, ssh2, ftpext et ftpsockets.
L’erreur persiste alors que les droits sont bons, que vérifier ?
L’espace disque et les inodes (df -h, df -i), la directive open_basedir, SELinux ou AppArmor et l’éventuel attribut immuable. Si le site est en conteneur, vérifiez que le volume n’est pas monté en lecture seule.