How to configure CORS on Apache HTTP Server

Enable Cross-Origin Resource Sharing (CORS) on Apache HTTP Server using mod_headers in the server config, VirtualHost, or .htaccess file.

Configure Cross-Origin Resource Sharing (CORS) headers on Apache HTTP Server to allow cross-origin requests from specific domains or all origins.

Prerequisites

  • Apache HTTP Server 2.4 or later installed and running.
  • Root or sudo access to the server.
  • The mod_headers module available (included in most Apache installations).

Step-by-Step: Enable CORS on Apache HTTP Server

  1. Enable the mod_headers module on Apache HTTP Server. This module provides the Header directive that sets CORS response headers.

    Run the following command on Ubuntu or Debian to enable mod_headers:

    sudo a2enmod headers

    On CentOS or RHEL, confirm that the module is loaded in the Apache configuration:

    httpd -M | grep headers
  2. Add the Cross-Origin Resource Sharing (CORS) headers to the Apache configuration. Choose one of three locations depending on the scope.

    Option A: Server or VirtualHost configuration-- Add the Header directive inside the <VirtualHost> block or the <Directory> block in the main configuration file:

    <VirtualHost *:443>
        ServerName api.example.com
    
        Header always set Access-Control-Allow-Origin "https://app.example.com"
        Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
        Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
        Header always set Access-Control-Max-Age "86400"
    
        # Handle preflight OPTIONS requests
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} OPTIONS
        RewriteRule ^(.*)$ $1 [R=204,L]
    </VirtualHost>

    Option B: .htaccess file-- Add the CORS headers to the .htaccess file in the document root. This approach requires AllowOverride FileInfo or AllowOverride All in the server configuration:

    <IfModule mod_headers.c>
        Header always set Access-Control-Allow-Origin "https://app.example.com"
        Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
        Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
    </IfModule>

    Option C: Allow all origins-- Replace the specific origin with the wildcard * for public APIs that do not use credentials:

    <IfModule mod_headers.c>
        Header always set Access-Control-Allow-Origin "*"
    </IfModule>

    Use Header always set instead of Header set to ensure Apache returns CORS headers on error responses (4xx and 5xx status codes).

  3. Test the Apache configuration for syntax errors before restarting:

    sudo apachectl configtest
  4. Restart Apache HTTP Server to apply the CORS configuration:

    sudo systemctl restart apache2

    On CentOS or RHEL, use httpd instead of apache2:

    sudo systemctl restart httpd

How to Verify CORS Is Working on Apache

Send a test request with curl to confirm Apache returns the Cross-Origin Resource Sharing (CORS) headers:

curl -I -H "Origin: https://app.example.com" https://api.example.com/

The response should include the Access-Control-Allow-Origin header matching the origin:

Access-Control-Allow-Origin: https://app.example.com

Test the preflight response by sending an OPTIONS request:

curl -X OPTIONS \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: PUT" \
  -H "Access-Control-Request-Headers: Content-Type, Authorization" \
  -i https://api.example.com/

Common Issues When Configuring CORS on Apache

  • mod_headers not loaded.Apache ignores Header directives when mod_headers is not enabled. Run sudo a2enmod headers and restart Apache.
  • Duplicate CORS headers.Both Apache and the application framework set Access-Control-Allow-Origin, causing two values in the response. The browser rejects responses with duplicate CORS headers. Configure CORS in one layer only.
  • .htaccess ignored.Apache skips .htaccess files when AllowOverride is set to None. Set AllowOverride FileInfo in the <Directory> block for the document root.
  • Preflight fails with 405 Method Not Allowed.Apache rejects OPTIONS requests when no handler is configured for that method. Add a RewriteRule that returns 204 for OPTIONS requests.

For a detailed explanation of the CORS preflight mechanism, see CORS tutorial: How Cross-Origin Resource Sharing works.