---
name: "PAR::Packer::Troubleshooting"
section: "3pm"
platform: "linux"
package: "perl-par-packer"
version: "1.064-6"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/PAR::Packer::Troubleshooting"
---

# PAR::Packer::Troubleshooting(3pm)

Common Problems Packing Scripts with pp

## NAME

PAR::Packer::Troubleshooting - Common Problems Packing Scripts with pp

## SYNOPSIS

Explain some common problems and remedies when packing scripts with *pp*.

## DESCRIPTION

### Missing modules

When you run the packed executable, it aborts with a message similar to

```
    Can't locate Foo/Bar.pm in @INC (you may need to install the Foo::Bar module)
      (@INC contains: ...) at script/pp5yBDq.pl line 1.
    BEGIN failed--compilation aborted at script/pp5yBDq.pl line 1.
```

Your script `"require"`s module `"Foo::Bar"` (perhaps indirectly from another module), but *pp* did not pack it into the executable. *pp* uses Module::ScanDeps to recursively scan your script for `"require"`ed modules. Sometimes this scan is incomplete due to the  many ways Perl allows you to express your desire to load a module.

Try to pack with options **--compile** or **--execute** to resolve the problem. If this fails, explicitly add the indicated module with option **-M**, i.e.

```
    % pp -M Foo::Bar ...
```

You may have to repeat adding modules, the wildcard variants of **-M** may come in handy here.

### Missing native DLLs

The packed executable runs fine on the machine where it was generated, but aborts with a message similar to the following when run on another machine (that may not have Perl installed)

```
    Can't load 'C:\Users\myuser\AppData\Local\Temp\3\par-74686f6b65\temp-1772\inc\lib/auto/Net/SSLeay/SSLeay.dll' for module Net::SSLeay:
      load_file:The specified module could not be found at <embedded>/DynaLoader.pm line 206. at <embedded>/PAR/Heavy.pm line 95.
```

Here the DLL part (*.../auto/Net/SSLeay/SSLeay.dll*) of an XS module (Net::SSLeay)  **has** been packed, but it's linked against a native DLL that has **not** been packed. The native DLL is obviously present on the machine used to pack, but not on the other machine. Note that *pp* (or rather Module::ScanDeps) does **not** detect such a non-Perl dependency and hence won't pack the native DLL, you would have to add it by hand (using  option **--link**).

**TL;DR** Use *pp\_autolink* from `"App::PP::Autolink"` to automate  packing in native DLLs and be done with it or read on for the gory details.

Inspecting *.../auto/Net/SSLeay/SSLeay.dll* (using tools like *objdump*) shows that it's linked against native DLLs *libssl\*.dll* and *libcrypto\*.dll*. These DLLs come from *OpenSSL*. Note the wildcards in the above filenames, they stand for version numbers. Once you have the exact filenames, you can add theses DLLs to the *pp* command line with `"--link ..."`. But we're not done: *libcrypto\*.dll* is typically linked against *libz\*.dll*, so you have to `"--link ..."` that one, too. Note that this example uses the Windows specific suffix ".dll", but the problem also exists on Linux or macOS.

### "Attempt to reload ... aborted. Compilation failed in require ..."

There are several scenarios where "Attempt to reload ..." can be emitted: it's just an indication that a previous `"require"` of *something* failed, but this error was suppressed, and then *something* was `"require"`d again. The original error would have told us the actual reason, but it's gone.

Here's an example, *foo.pl*.

```
    use strict;
    use warnings;
    use feature qw( say state );
    eval {
        say "first Foo";
        require Foo;
    };
    #say "require failed: $@" if $@;   # <---
    say "Text::ParseWords ...";
    require Text::ParseWords;
    say "second Foo";
    require Foo;
```

Now run

```
    % echo "use Bar; 1;" > Foo.pm
    % echo "use Quux; 1;" > Bar.pm
    % perl -I. foo.pl
    first Foo
    Text::ParseWords ...
    second Foo
    Attempt to reload Foo.pm aborted.
    Compilation failed in require at foo.pl line 28.
```

Uncomment the line with the arrow to see the actual reason:  "Can't locate Quux.pm in `@INC` ... at Bar.pm line 1.", i.e. *Quux.pm* is missing. Note that the original error message doesn't mention "Quux.pm".

Now try this:

```
    % echo "{" > Quux.pm        # yes, that's a syntax error
    % perl -I. foo.pl
    first Foo
    Text::ParseWords ...
    second Foo
    Attempt to reload Foo.pm aborted.
    Compilation failed in require at foo.pl line 28.
```

Same output as above.  Again, uncomment the line with the arrow to see the actual reason:  "Missing right curly or square bracket at Quux.pm line 1 ... syntax error at Quux.pm line 1, at EOF". So *Quux.pm* exists, but could not be  loaded due to a syntax error. There are other reason why loading a module might fail, e.g. "Missing native DLLs".

Here's a recipe to narrow down the problem. Add the following **before the first Perl statement** of *foo.pl*:

```
    BEGIN {
        my $required;
        unshift @INC, sub {
            (undef, $required) = @_;
            my (undef, $filename, $line) = caller();
            print STDERR "require $required from ${filename}:${line}\n";
            return;
        };
        push @INC, sub { print STDERR "MISSING $required\n"; return; };
    }
```

This logs any attempt to `"require"` *something* including the call site. It can't record whether the `"require"` succeeded nor the error in case it failed. But if the failure is simply a missing module, it will print "MISSING *something*".

Now try the two variants above again. Here's the "missing module" case (showing only `"stderr"`):

```
    require strict.pm from foo.pl:14
    require warnings.pm from foo.pl:15
    require feature.pm from foo.pl:16
    require Foo.pm from foo.pl:22
    require Bar.pm from Foo.pm:1
    require Quux.pm from Bar.pm:1
    MISSING Quux.pm
    require Text/ParseWords.pm from foo.pl:27
    require Exporter.pm from /usr/lib/x86_64-linux-gnu/perl-base/Text/ParseWords.pm:8
    Attempt to reload Foo.pm aborted.
    Compilation failed in require at foo.pl line 28.
```

and the "failing to load" case:

```
    require strict.pm from foo.pl:14
    require warnings.pm from foo.pl:15
    require feature.pm from foo.pl:16
    require Foo.pm from foo.pl:22
    require Bar.pm from Foo.pm:1
    require Quux.pm from Bar.pm:1
    require Text/ParseWords.pm from foo.pl:27
    require Exporter.pm from /usr/lib/x86_64-linux-gnu/perl-base/Text/ParseWords.pm:8
    Attempt to reload Foo.pm aborted.
    Compilation failed in require at foo.pl line 28.
```

So the strategy to find the cause for "Attempt to reload *something*" is:

- •

  Find the first occurence of "require\> *something*" in the ouput.

- •

  Walk down the "call chain" of nested `"require"`s while staying "below" *something*. The culprit is typically the last module mentioned on a "require ... from ..." line.

- •

  If the next line is "MISSING *something*" then it's a case of "Missing modules" with *something* the culprit. Otherwise it's a failure to load *something*, probably "Missing native DLLs".

In the above example the "call chain" is

```
  foo.pl -> Foo.pm -> Bar.pm -> Quux.pm
```

(*Text/ParseWords.pm* is `"require"`d from *foo.pl*, hence "above" *Foo.pm*). This would implicate *Quux.pm*. Note that the "call chain" doesn't have to look regular like above, that's only the case if all `"require"`s stem from `"use"` statements that are executed at **compile** time. The picture may be skewed if **runtime** `"require"` statement are used.

## SEE ALSO

pp, App::PP::Autolink, PAR, PAR::Packer

## COPYRIGHT

Copyright 2025 by Roderich Schupp \<roderich.schupp@gmail.com\>.

This document is free documentation; you can redistribute it and/or modify it under the same terms as Perl itself.

See *LICENSE*.
