Disabling HTTP methods that the site does not use reduces Apache's exposed request surface and stops clients from reaching request paths the application never intended to serve. A tight method allowlist also makes unexpected 405 or 403 responses easier to interpret during security reviews and log analysis.
Apache 2.4 can scope access rules to request verbs inside request-matching sections such as <Location>. A core <LimitExcept> block with Require all denied works on a standard install without loading another module, and Apache treats GET and HEAD as equivalent inside that allowlist.
Pick the allowlist before reloading the vhost. Browsers may need OPTIONS for CORS preflight, APIs may legitimately require PUT, PATCH, or DELETE, and TRACE is not controlled by <LimitExcept>, so keep TraceEnable off as a separate hardening setting and validate the configuration before applying it.
Related: How to test Apache configuration
Related: How to manage the Apache web server service
$ sudo vi /etc/apache2/sites-available/000-default.conf
On Debian and Ubuntu, enabled vhosts are typically linked from /etc/apache2/sites-enabled. If the site also serves HTTPS, update the matching TLS vhost such as /etc/apache2/sites-available/default-ssl.conf as well.
<VirtualHost *:80> ServerName host.example.net DocumentRoot /var/www/html TraceEnable off </VirtualHost>
Do not rely on <LimitExcept> to block TRACE. Apache controls TRACE separately with TraceEnable.
<VirtualHost *:80> ServerName host.example.net DocumentRoot /var/www/html TraceEnable off <Location "/"> <LimitExcept GET POST> Require all denied </LimitExcept> </Location> </VirtualHost>
Any method not named inside <LimitExcept> is denied. Add OPTIONS when browser clients need CORS preflight, and keep verbs such as PUT, PATCH, or DELETE only when the application actually uses them.
Method names are case-sensitive. Apache treats GET and HEAD as equivalent here, so allowing GET also keeps HEAD working.
$ sudo apache2ctl configtest Syntax OK
Use sudo apachectl -t or sudo httpd -t on platforms that ship different control wrappers.
Related: How to test Apache configuration
$ sudo systemctl reload apache2
On hosts where systemd is not managing Apache directly, use sudo apache2ctl graceful or the platform-equivalent reload command instead.
$ sudo systemctl is-active apache2 active
If the service does not report active, inspect the journal or error log before retrying the reload.
$ curl -sS -D - -o /dev/null -X TRACE -H 'Host: host.example.net' http://127.0.0.1/ HTTP/1.1 405 Method Not Allowed Date: Thu, 09 Apr 2026 04:39:39 GMT Server: Apache/2.4.58 (Ubuntu) Allow: Content-Length: 304 Content-Type: text/html; charset=iso-8859-1
A 405 Method Not Allowed response here confirms that TraceEnable off is active for the request.
$ curl -sS -D - -o /dev/null -X PUT -H 'Host: host.example.net' http://127.0.0.1/ HTTP/1.1 403 Forbidden Date: Thu, 09 Apr 2026 04:39:39 GMT Server: Apache/2.4.58 (Ubuntu) Content-Length: 281 Content-Type: text/html; charset=iso-8859-1
If this request must succeed for the application, add that method to the <LimitExcept> list before reloading again.
$ curl -sSI -H 'Host: host.example.net' http://127.0.0.1/ HTTP/1.1 200 OK Date: Thu, 09 Apr 2026 04:39:40 GMT Server: Apache/2.4.58 (Ubuntu) Last-Modified: Thu, 09 Apr 2026 04:39:36 GMT ETag: "2c-64eff9a8baf52" Accept-Ranges: bytes Content-Length: 44 Content-Type: text/html