Skip to content

Exim 4.100: "$ver >= 4.97" compares as a float, so long message IDs are not detected and every message is stranded ("Spool file -D not found") #717

Description

@jkeyseraolc

Summary

With Exim 4.100, MailScanner decides that Exim uses the old short message-ID format. It then files every scanned message in the wrong split-spool subdirectory, where the delivering Exim never looks. Mail is accepted but nothing is delivered, and every message logs Spool file <id>-D not found. Exim 4.100 is now being rolled out (for example cpanel-exim-4.100, September 2026), so affected hosts break on update.

Cause

common/usr/sbin/MailScanner (master):

    $ver = $line[2];
    $ver =~ /\d+\.\d+/;
  ...
  if ($ver >= 4.97) {
    MailScanner::Config::SetValue('eximlongids',1);
  } else {
    MailScanner::Config::SetValue('eximlongids',0);
  }

>= is a numeric comparison, and Perl numifies "4.100" to 4.1, which is less than 4.97. So eximlongids becomes 0. (The $ver =~ /\d+\.\d+/; line runs in void context and changes nothing.)

$ perl -e 'my $ver = "4.100"; print(($ver >= 4.97) ? "long\n" : "short\n")'
short

With eximlongids = 0, EximDiskStore::OutQDir uses offset -13. On the 4.97+ ID format (1x4x7i-0000000GmSQ-0zdV-D), that character falls inside the zero-padded PID field, so it is almost always 0. Every message is written to input/0/, while Exim looks in input/<6th character of the id>/. Because the script sets eximlongids itself at start-up, it cannot be overridden in MailScanner.conf.

Suggested fix

Compare major and minor as integers:

  my ($vmaj, $vmin) = $ver =~ /^(\d+)\.(\d+)/;
  if (defined $vmaj && ($vmaj > 4 || ($vmaj == 4 && $vmin >= 97))) {
    MailScanner::Config::SetValue('eximlongids',1);
  } else {
    MailScanner::Config::SetValue('eximlongids',0);
  }

This gives: 4.96 → short, 4.97 / 4.98 / 4.100 / 5.0 → long.

Recovering stranded mail

After fixing and restarting MailScanner, move each stranded message's -H and -D from input/0/ into input/<6th character of the id>/ of the outgoing spool, then run a queue run. The files themselves are intact.

Note for packagers

ConfigServer's MailScanner Front-End (MSFE) bundle has the same float check. There it chooses between EximDiskStore.pm and EximDiskStoreNew.pm, so the same fix applies.

Activity

  1. github-actions commented on Sep 11, 2026

    @github-actions

    Thank you for submitting your first issue to MailScanner! We will respond to you soon!

  2. josaladino2 commented on Sep 12, 2026

    @josaladino2

    alternative solution:
    my @out = exim -bV;
    my @line = split(/ /, $out[0]);
    my $ver = $line[2];

    if ($ver >= 4.97) {
    $MTAmod = 'Exim.pm';
    $MTADSmod = 'EximDiskStoreNew.pm';
    }

  3. uwallrodt commented on Sep 14, 2026

    @uwallrodt
    Contributor

    Credit where due — the diagnosis and fix here were originally posted by nickgr on cPanel's own community forum, in the thread "Hundreds of emails stuck in progress" (same $ver >= 4.97 numeric-comparison root cause as this issue, and he links it here himself). Quoting his fix:

    Fix: edit /usr/mailscanner/usr/sbin/MailScanner ... and replace the line if ($ver >= 4.97) { with:
    my ($vmaj, $vmin) = $ver =~ /^(\d+)\.(\d+)/; if (defined $vmaj && ($vmaj > 4 || ($vmaj == 4 && $vmin >= 97)))

    Can confirm it works in production too: applied it to a cPanel server hit by the same bug (Exim 4.100, MailScanner 5.4.4) — messages accepted then permanently stuck, -Mrm/-Mvh/-qff all failing with "Spool file ... -D not found" despite the file existing on disk. Restarted MailScanner + Exim after patching and mail flow recovered immediately, no recurrence since. Several others on that cPanel thread confirmed the same fix independently.

    Worth merging — this silently breaks mail delivery on any cPanel box that picks up Exim 4.100, with no warning beyond the queue quietly growing.

  4. added a commit that references this issue on Sep 14, 2026
    fc6f0ae
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions