I was wondering if it's possible to make nodes without path alias not accessible. By this I mean that visiting /node/$nid/ users will not be able to see its content, but if that node has an path alias (e.g. /myarticle/my-article-name/) the node will be visible using the path alias.

Is it possible to achieve it with code?

By researching, I found that I can do this in hook_menu() with either $items['node/%node']['page callback'] = 'drupal_not_found'; or $items['node/%node']['access'] = FALSE;.

The problem is that I can't access with /node/$nid/ and without /myarticle/my-article-name/, it raises permission denied.

  • No, hook_menu() is the wrong hook to use to alter a route defined from another module. In your case, not even hook_menu_alter() would work.
    – apaderno
    Commented Nov 19, 2017 at 8:11

3 Answers 3


hook_menu() is not the hook to alter the routes defined from other modules, but in this case not even hook_menu_alter() would help.

When users access a page using a path alias, Drupal gets the normal path (i.e. the path to which the path alias points) before rendering the page. So, for Drupal, users are always visiting /node/$nid, not /myarticle/my-article-name/. In fact, drupal_path_initialize() (called at bootstrap time) contains the following code.

  if (empty($_GET['q'])) {
    $_GET['q'] = variable_get('site_frontpage', 'node');
  $_GET['q'] = drupal_get_normal_path($_GET['q']);

drupal_get_normal_path() is the function converting the path alias in the internal path.

In this case, a redirect from /node/$nid to /myarticle/my-article-name/ is, IMO, the solution. The Global Redirect module already does that, as the project page describes.

  1. Checks the current URL for an alias and does a 301 redirect to it if it is not being used.
  2. Checks the current URL for a trailing slash, removes it if present and repeats check 1 with the new request.

Also, notice the Why? section on that page.

Once enabled, an alias provides a nice clean URL for a path on a site. However Drupal does not remove the old path (eg node/1234). The problem is that you now have two URLs representing the same content. This is dangerous territory for duplicate pages which can get you sandboxed by the search engines!


I have searched all over, and pretty much in all cases, no one understands the problem. I don't have the answer, but can only provide more clarity for the problem, and a suggestion for the best place for a solution ...


  1. BLOCK access for anonymous users using /node/{nid} in the PATH
  2. Still render the page for anonymous users USING THE ALIAS for the node
  3. AGAIN, 1. BLOCK access for anonymous users (NOT ALL USERS) using /node/{nid} (stating this again, because most solutions are about redirecting, and that does not block.
  4. Make sure that authenticates users can still edit the node, which will contain /node/{nid} in the path

WHY DO WE WANT TO BLOCK access to the node using /node/{nid} in the path? Because, it is easy for anyone to get access to information by just modifying the path ... going /node/1, then /node/2, then /node/3, etc. With pathauto, the alias are shown, but the content is found. And what is the use of a complex pathauto, if there are 2 ways to get to the content ... not just for SEO, but also for just not simply wanting to give people easy access to all info. E.g. when usign pathauto with hash alias for the content.


  1. A modification of PathAuto will be the best solution as it handles the redirect from node/{nid} to alias and alias to /node/{nid}
  2. PathAuto requires a feature/setting whereby admin can indicate that the internal path needs to be CLOAKED for anonymous users (by pattern, or specific to a node).
  3. If internal path is CLOAKED, then requests from anonymous users using /node/{nid} must redirect to a defined node indicating whatever, e.g. NO ACCESS, or just defining the node as the FRONT PAGE. This will effectively BLOCK access using /node/{nid}.
  4. If the request uses the alias in the path, then all good to access the node - regardless of user role.


  1. Any .htaccess solution - because htaccess does not know if the user is anonymous or authenticated in Drupal.
  2. Any global redirect solution to the alias - because redirect does NOT BLOCK the content when using /node/{nid} in the path
  3. Any other module used together with PathAuto, as they will have conflicting logic, and this usage scenario is a modification of how pathauto should handle redirects for anonymous users.

Hoping that this helps you and others to eventually get a solution. It is a pretty simple and anoying problem with Drupal - 2 accesses to the content, and 1 giving a particularly easy way for people to dig through info on your site, when you need just a slight bit of hiding, especially when the use case scenario does not warrant authentication overhead.


I've created a module and is busy adding it to Drupal site. The code is available here for download.


The intended use of the module is to redirect GUEST / ANONYMOUS users when they access content in Drupal using URL /node/{id}. Many sites make use of URL ALIAS and don't want users necessarily to scan content out of context using /node/{id}.

The module simply "hooks" into / subscribes to kernel.request and matches the request uri with a regular expression that is configured (default is '~/node/d*~i'). If there is a match, and the user is ANONYMOUS, it will route the user to a route that has been configured (default set to '/home').

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.