Carnet de Nicolas
Journal de bord et autres pérégrinations de l’esprit

Résoudre les erreurs Apache « File not found » et « Primary script unknown »

Avec les ajustements effectués pour PHP 8.2 suite à la migration vers Debian 12, je pensais avoir fait le tour des erreurs rencontrées et les avoir corrigées. Et puis, en accédant à une page qui n’existe pas, j’ai eu cette page blanche avec l’erreur File not found au lieu d’avoir une page d’erreur 404 personnalisée.

Page d’un navigateur sur URL inexistante qui affiche une page blanche avec le texte « File not found. ».
Erreur « File not found » affichée au lieu d’une erreur 404 personnalisée.

Dans les journaux d’erreur d’Apache, je trouve une entrée correspondante à l’accès de cette page, que je n’avais encore jamais rencontrée.

… [proxy_fcgi:error] Got error 'Primary script unknown'

Grâce à cette réponse partagée sur StackExchange, le coupable est bien lié à PHP 8.2 et au module PHP-FPM associé — c’est une sorte d’intermédiaire entre Apache et PHP, qui permet normalement d’améliorer les performances dans l’exécution des requêtes dynamiques. L’erreur affichée File not found sur la page web signifie que c’est le moteur PHP-FPM qui a essayé de traiter la demande de cette URL inexistante, au lieu de laisser Apache s’en occuper. Heureusement, il est possible de modifier le comportement de PHP-FPM.

Dans le fichier /etc/apache2/conf-enabled/php8.2-fpm.conf, on va sélectionner la configuration qui vérifie que le script existe au préalable :

  • on commente les lignes 11 à 13 ;
  • on décommente les lignes 18 à 22.

Normalement, le fichier doit avoir été modifié ainsi :

# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php8.c>
<IfModule proxy_fcgi_module>
    # Enable http authorization headers
    <IfModule setenvif_module>
    SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>

    # Using (?:pattern) instead of (pattern) is a small optimization that
    # avoid capturing the matching pattern (as $1) which isn't used here
    #<FilesMatch ".+\.ph(?:ar|p|tml)$">
    #    SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
    #</FilesMatch>
# The default configuration works for most of the installation, however it could
# be improved in various ways. One simple improvement is to not pass files that
# doesn't exist to the handler as shown below, for more configuration examples
# see https://wiki.apache.org/httpd/PHP-FPM
    <FilesMatch ".+\.ph(?:ar|p|tml)$">
        <If "-f %{REQUEST_FILENAME}">
            SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
        </If>
    </FilesMatch>
    <FilesMatch ".+\.phps$">
        # Deny access to raw php sources by default
        # To re-enable it's recommended to enable access to the files
        # only in specific virtual host or directory
        Require all denied
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(?:ar|p|ps|tml)$">
        Require all denied
    </FilesMatch>
</IfModule>
</IfModule>

On redémarre ensuite Apache pour que la configuration soit prise en compte.

systemctl restart apache2
Page d’un navigateur sur URL inexistante qui affiche une page d’erreur 404 personnalisée.
Page 404 personnalisée affichée pour une URL inexistante.

Le comportement existant affichant la page d’erreur 404 personnalisée est maintenant bien rétabli. Youpi !