The Puppet Labs Issue Tracker has Moved:

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using See the following page for information on filing tickets with JIRA:

Bug #21428

puppet class namespace length limit causes incorrect loading of classes

Added by Tim Mooney almost 3 years ago. Updated almost 3 years ago.

Status:Ready for DocumentationStart date:
Priority:HighDue date:
Assignee:Charlie Sharpsteen% Done:


Target version:-
Affected Puppet version:2.7.14 Branch:

We've Moved!

Ticket tracking is now hosted in JIRA:


We’re running 2.7.14. (Yes, we know — some of the changes later in the 2.7.x series make it difficult for us to upgrade to anything later until we rework some of our modules).

We’ve been moving to the “role/profile” puppet module pattern. As a result, we’ve been getting some longer class namespaces, e.g. profile::foo::bar::baz. I’ve discovered that the “include” mechanism and the dependency graph apparently cannot tell the difference between “class baz” and “class profile::foo::bar::baz”.

I’ll attach a tarball with all the modules and the site.pp that reproduces the problem.

Here’s class “baz”:

$ cat modules/baz/manifests/init.pp
class baz {
  notify { 'baz-notify':
    message => "notify from class baz\n"

Here’s class profile::foo::bar::baz:

$ cat modules/profile/manifests/foo/bar/baz.pp 
class profile::foo::bar::baz {
  include baz
  notify { 'profile-foo-bar-baz-notify':
    message => "notify from class profile::foo::bar::baz\n"
  Notify['profile-foo-bar-baz-notify'] -> Class['baz']

Here’s a simple “site.pp” to trigger the problem:

$ cat manifests/nodes/site.pp 
node default {
  include profile::foo::bar::baz

Here’s what I get:

$ puppet apply --verbose manifests/nodes/site.pp 
info: Applying configuration version '1372118584'
err: Could not apply complete catalog: Found 1 dependency cycle:
(Notify[profile-foo-bar-baz-notify] => Class[Profile::Foo::Bar::Baz] => Notify[profile-foo-bar-baz-notify])
Try the '--graph' option and opening the resulting '.dot' file in OmniGraffle or GraphViz
notice: Finished catalog run in 0.03 seconds

Notice that even though the dependency ordering I had set up had the Notify before Class[‘baz’], puppet became mixed up and instead used Class[‘profile::foo::bar::baz’], which obviously caused the dependency cycle.

If you comment out the ordering relationship in modules/profile/manifests/foo/bar/baz.pp, you instead get:

$ puppet apply --verbose manifests/nodes/site.pp 
info: Applying configuration version '1372121784'
notice: notify from class profile::foo::bar::baz

notice: /Stage[main]/Profile::Foo::Bar::Baz/Notify[profile-foo-bar-baz-notify]/message: defined 'message' as 'notify from class profile::foo::bar::baz'
notice: Finished catalog run in 0.04 seconds

Notice that even though “profile::foo::bar::baz” is still doing an “include baz”, it never gets included. I’m theorizing that the class loader is confused and thinks that the original “include profile::foo::bar::baz” from the site.pp is causing puppet to think that Class[‘baz’] is already loaded, even though it’s not.

puppet-deep-namespace-bug.tar.gz - tar file contining the site.pp and modules that illustrate the problem (771 Bytes) Tim Mooney, 06/24/2013 06:13 pm

Related issues

Duplicates Puppet - Bug #2053: Relative namespacing of class/define names results in big... Accepted 03/06/2009


#1 Updated by Charlie Sharpsteen almost 3 years ago

  • Category changed from autoloader to modules
  • Status changed from Unreviewed to Duplicate
  • Assignee set to Charlie Sharpsteen
  • Keywords set to namespaces

This is the result of how Puppet performs namespace lookup. If you want to access the top-level class baz instead of the local class profile::foo::bar::baz, then you need to prepend the top-level class with ::

class profile::foo::bar::baz {                             
  include ::baz                                          
  notify { 'profile-foo-bar-baz-notify':                   
    message => "notify from class profile::foo::bar::baz\n"
  Notify['profile-foo-bar-baz-notify'] -> Class['::baz']   

This lookup behavior is also present in Puppet 3.x.

#2 Updated by Tim Mooney almost 3 years ago

Thanks for the explanation Charlie. I had searched for this being reported before and didn’t turn up the issue it duplicates — sorry. I’ve also been through the updated puppet 2.7 reference guide a bunch (it’s a huge improvement over the older docs!) but had somehow missed that. I had been concentrating my review in the modules section, specifically

The “Manifests” and “Allows Module Names” section might really benefit from a link to the “Classes and Autoloading” section.

I was aware that in 2.7.x and later we had to be more careful about scoping facts, but even after a couple of years of using puppet I had no idea that class scoping worked this way.

You’ve given me a usable workaround, though I do agree with issue # 2053 and what the reference guide says — this is a trap for the unwary and it should definitely be fixed, when a reasonable fix can be agreed upon.

I may also see if I can provide a patch for the docs, so that the section I was looking at has a clear and visible link to the autoloader section that clearly explains this deficiency.

Thanks for your time and attention on this one.


#3 Updated by Charlie Sharpsteen almost 3 years ago

  • Status changed from Duplicate to Ready for Documentation

Thanks a bunch for the documentation suggestions. If you can contribute a patch to our documentation project that would be fantastic! Just open a pull request and it will be reviewed.

I am also marking this ticket as needing documentation work so that it can be addressed in a future docs sweep if we don’t get a pull request.

Also available in: Atom PDF