Over the last year, a handful of CPAN authors have been bitten by PAUSE complaining that they don’t have permissions for a distribution name they’ve uploaded.

PAUSE used to have a gaping security hole; it’s now closed. As a result, when an author uploads a distribution with a name like Foo-Bar-Baz-1.23.tar.gz, the author must have primary or co-maintainer permissions on the package name matching the distribution (Foo::Bar::Baz, in this case) or else the distribution will not be indexed. It’s still on CPAN, but won’t be added to the index that allows people to easily install it.

How to fix it 🔗︎

If you are uploading Foo-Bar-Baz-1.23.tar.gz, make sure you have a “lib/Foo/Bar/Baz.pm” file containing a “package Foo::Bar::Baz” statement.

If you use any sort of clever syntax mangler like Moops that doesn’t use “package” statements, be sure your generated META.json or META.yml file includes a “provides” field claiming the package name matching the distribution name. If you don’t understand what that means or how to make it happen, you shouldn’t be using Moops or anything like it until you do. (Update: I posted an example in ““How to add ‘provides’ metadata via Makefile.PL”.)

Many CPAN ecosystem tools (like rt.cpan.org) treat a distribution (i.e. tarball) name as a significant entity for permissions, etc. But historically, nothing required distribution names to have anything to do with the modules they contained. This led to an interesting security hole: by uploading a distribution matching an existing distribution on CPAN, but with entirely new, unrelated modules, PAUSE would index the modules and associate them with the distribution. The author of said distribution would then be treated as a fully-authorized administrator over the shared distribution name.

Example: Let’s say I wanted to hijack the Moose RT queue. I could have uploaded Moose-666.tar.gz containing lib/Not/Really/Moose.pm with “package Not::Really::Moose” and a $VERSION of 666. That would create an index entry like this:

Not::Really::Moose 666 DAGOLDEN/Moose-666.tar.gz

‘lo and behold, because I had an indexed distribution “DAGOLDEN/Moose-666.tar.gz”, I would become an administrator of the Moose RT queue. And MetaCPAN would think that “666” was the latest release of Moose.

To fix this, PAUSE now ties distribution names to the package namespace permissions system. While I can still upload Moose-666.tar.gz, because I don’t have permissions over the “Moose” package name, my bogus distribution would not be indexed. Without being indexed, the ecosystem doesn’t use it to give me any permissions.

A small handful of distributions were grandfathered (e.g. libwww-perl) and don’t have to follow this rule, but all new distributions do.

Unfortunately, PAUSE’s upload reporting has some bugs and other distribution problems can wind up incorrectly reported as a permissions problem. These are actually pretty rare. Still, I hope to work with Andreas at the QA hackathon to fix the upload reporting.

But if you get this error message, it’s 90% or more likely that you’ve got one of these problems:

You don’t have a module “Foo::Bar::Baz” in a distribution called Foo-Bar-Baz-$VERSION.tar.gz; fix it by adding that module You think you have a “Foo::Bar::Baz” module, but PAUSE can’t find it or understand your package declaration; fix your package declaration or use a ‘provides’ field in META.json to be explicit You have a “Foo::Bar::Baz” module, PAUSE can find it, but for some weird, historical reason someone *else* actually owns that namespace and you never noticed before

If you’ve ruled out #1 and #2 yourself, please feel free to contact modules@perl.org for help, but be patient, as it make take a while for an admin to see your email and investigate.

I hope this explanation helps anyone mystified by this error message.