Finding the source of an unwanted 301 or 302 redirect

One challenge encountered by many Drupal site builders and developers is finding the source of an unwanted HTTP 301 or 302 redirect which is preventing viewers from accessing their site's content via the web. Finding the place in your site's code or configuration where this unwanted redirect is being triggered can be a tricky and frustrating task. In this article, we'll discuss a couple of techniques you can use to rule out or narrow in on the potential sources of 301 and 302 redirects on your site.

1. Use the right debugging tools.

Our first recommendation for troubleshooting this issue is to use a tool that allows you to

  • Examine the response headers sent by the server when these redirects occur.
  • Follow multiple redirects

If you're comfortable with the command line, the following tools are just a few of the available options for this task:

  • cURL, with the "-L" (follow redirects) and "-IX GET"  (send a GET request, but display only the response headers, not the response body) options.
  • Wget, with the "-qSO /dev/null" (suppress all output except the server's response headers) output. Wget sends GET requests and will automatically follow up to redirects by default.

If you're not comfortable with command-line tools, there are also many browser-based options available. For example:

  • Redirect Check, (website) given an URL, Redirect Check will trace its redirection path, reporting the response headers returned by the server for each request.
  • The Network Inspection tools provided by Google Chrome or Mozilla Firefox (browser tools). These tools can be used to record the requests made by your web browser, allowing you to inspect their response headers.

2. Know the difference between 301 and 302.

The HTTP response code returned with a redirect can provide valuable insight into its intended purpose, and how web proxies and browsers may use when deciding how to handle future requests to the redirected URL.

  • 301 "Moved Permanently": This type of redirect is meant to imply that the requested resource has moved permanently to a new location, and can be cached by proxy servers and web browsers. If you're trying to troubleshoot this type of redirect, be sure to check the "Cache-Control" and "X-Cache" response headers sent by the server to determine if the redirect is being served from a cache (e.g: Varnish on your Acquia Cloud load balancers) that may need to be cleared before the issue is resolved.
  • 302 "Found" or "Moved Temporarily": This redirect type implies a temporary or "one-time" redirect, that should not be cached by web proxies or browsers. Notably, this is the default status code returned by Apache's Rewrite module for redirects defined via RewriteRules in an .htaccess or vhost configuration file, and is also the default status code for the drupal_goto function used by Drupal Core (version 7 and earlier) to redirect incoming requests.

3. Pay attention to the "Location" response header.

The Location response header returned by the server during a redirect will be used to make a subsequent HTTP request to the resource's updated location, and can be useful in debugging problematic redirects, especially redirect loops, in which the values specified in this header ultimately lead the requesting client back to the URL they originally requested, causing an infinite loop of web requests that will prevent web pages from resolving successfully. Paying attention to the value of this redirect should allow you to glean the intended purpose behind the redirect. Here are some examples of common redirection practices expressed by the "Location" header:

  • Redirecting between the HTTP and HTTPS versions of a page
  • Adding or removing the trailing slash (/) to or from the end of a request URL.
  • Redirecting between "www." and "bare" domains (e.g: redirecting "" to "", and vice versa).
  • Redirecting to a Drupal page's updated URL alias after a content change has been saved.

Paying attention to how this header changes as a request is updated from one URL to another, and using this information to determine what the redirect is attempting to accomplish can help you to narrow in on the part of your site's code or configuration responsible for generating the redirect.

4. Check for Server, Via, X-Generator, and X-Drupal-Cache response headers.

The ServerVia, X-Generator, and X-Drupal-Cache response headers can provide hints about which part of your web application is serving a redirect. For example, on an Acquia Cloud Drupal site:

  • The presence of the "X-Drupal-Cache" header (with any value) or the "X-Generator" header (with a value containing the word "Drupal" indicates that the response is being served by the Drupal CMS, and is likely the product of a contributed or custom module in your site's codebase.
  • If the "Server" header contains "Nginx", but neither of the Drupal-related headers mentioned above are present, the redirect is likely being triggered by a Rewrite Rule in your site's .htaccess file, especially if the "Location" header indicates one of the common redirection practices mentioned in section 3 above.
  • If Varnish on your site's load balancers is involved in serving the response, the software will add a "Via" response header, with a value containing "1.1 varnish". The presence of this header indicates that some logic in your site's Varnish Configuration (VCL) file may be responsible for serving the redirect you're troubleshooting, especially if you're using a customized VCL on your Acquia Cloud load balancers.
  • Finally, in some cases, the "Server" header can indicate the involvement of a Content Delivery Network (CDN) like CloudFlare or Akamai. A "Server" header containing a value like "AkamaiGhost" or "cloudflare-nginx", especially in the absence of the other headers discussed above, may indicate that some aspect of your CDN's functionality is responsible for generating this redirect.

5. Consider the involvement of these popular Drupal modules.

The following contributed Drupal modules are used on many sites to implement some common redirection behaviors. If these modules are enabled on your site, especially if the "X-Generator" or "X-Drupal-Cache" headers above are present in the redirect you're troubleshooting, you'll want to consider checking to ensure that they're configured properly:

  • Redirect provides an administrative interface, allowing site builders to redirect an incoming request to a URL of their choice, with a response code of their choice. This module also provides an API that can be used by other contributed and custom modules to implement their own redirection functionality. If you see a "X-Redirect-ID" response header with the redirect you're troubleshooting, the Redirect module is responsible, and you can use the value of this header to look up and edit the redirect in the module's administrative interface.
  • Global Redirect also provides some common redirection functionality, like "de-slashing" URLs and redirecting from system paths to path aliases.
  • Secure Pages performs a 302 redirect between the HTTP and HTTPS versions of Drupal pages on your site. In some cases, the use of this module in conjunction with .htaccess rules designed to redirect all incoming requests to HTTPS can cause a redirect loop.
  • The Internationalization (i18n) suite contains a module called Translation Redirect, which to redirect requests to the localized or translated versions of their content

Contact supportStill need assistance? Contact Acquia Support