Bug Report: lnms port:tune all all fails when interfaces have NULL ifSpeed after updating PHP

Hi Team Hi @murrant !

Please can you help me with this problem, when executing lnms port:tune all all

we start reciving this error.

Note: this start happening after we update the php

root@XXXXXXXX:/opt/librenms# php -v
PHP 8.4.27 (cli) (built: Oct 21 2026 07:53:46) (NTS)
Copyright (c) The PHP Group
Built by Debian
Zend Engine v4.4.27, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.27, Copyright (c), by Zend Technologies

The error:

lnms port:tune all all

....

TypeError

LibreNMS\Data\Store\Rrd::tune():
Argument #3 ($max) must be of type int, null given

In Rrd.php line 220


##################################################################


 Tuning port 100GE15/0/15
 Tuning port LoopBack25
Exception: TypeError LibreNMS\Data\Store\Rrd::tune(): Argument #3 ($max) must be of type int, null given, called in /opt/librenms/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 363 @ /opt/librenms/LibreNMS/Data/Store/Rrd.php:220
#0 /opt/librenms/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(363): LibreNMS\Data\Store\Rrd->tune()
#1 /opt/librenms/app/Console/Commands/PortTune.php(49): Illuminate\Support\Facades\Facade::__callStatic()
#2 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\Console\Commands\PortTune->handle()
#3 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#4 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure()
#5 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#6 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call()
#7 /opt/librenms/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\Container\Container->call()
#8 /opt/librenms/vendor/symfony/console/Command/Command.php(341): Illuminate\Console\Command->execute()
#9 /opt/librenms/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Command\Command->run()
#10 /opt/librenms/vendor/symfony/console/Application.php(1117): Illuminate\Console\Command->run()
#11 /opt/librenms/vendor/symfony/console/Application.php(356): Symfony\Component\Console\Application->doRunCommand()
#12 /opt/librenms/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun()
#13 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Console\Application->run()
#14 /opt/librenms/lnms(35): Illuminate\Foundation\Console\Kernel->handle()
#15 {main}  

In Rrd.php line 220:
                                                                                                                                                                                               
  LibreNMS\Data\Store\Rrd::tune(): Argument #3 ($max) must be of type int, null given, called in /opt/librenms/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 363  
                                                                                                                                                                                               

The stack trace pointed to:

/opt/librenms/app/Console/Commands/PortTune.php

where the code executes:

Rrd::tune('port', $rrdfile, $port->ifSpeed);

while the target method is defined as:

public function tune(string $type, RrdPath $rrd, int $max): bool

It seams that the problem is associated with the interfces that does not have ifSpeed, and return NULL

MariaDB [librenms]> SELECT
    ->     d.hostname,
    ->     p.port_id,
    ->     p.ifName,
    ->     p.ifDescr,
    ->     p.ifSpeed
    -> FROM ports p
    -> JOIN devices d ON d.device_id=p.device_id
    -> WHERE p.ifType='ethernetCsmacd'
    ->   AND p.ifSpeed IS NULL
    -> LIMIT 100;
+---------------+---------+----------+--------------------+---------+
| hostname      | port_id | ifName   | ifDescr            | ifSpeed |
+---------------+---------+----------+--------------------+---------+
| xxxxxxxxxxx   |  144237 | Et3/0    | Ethernet3/0        |    NULL |
| xxxxxxxxxxx   |  144261 | Et1/0    | Ethernet1/0        |    NULL |
| xxxxxxxxxxx   |  144262 | Et1/1    | Ethernet1/1        |    NULL |
| xxxxxxxxxxx   |  144282 | Fa0/0    | FastEthernet0/0    |    NULL |
| xxxxxxxxxxx   |  144283 | Fa0/1    | FastEthernet0/1    |    NULL |
| xxxxxxxxxxx   |  144302 | Fa0/0    | FastEthernet0/0    |    NULL |
| xxxxxxxxxxx   |  144303 | Fa0/1    | FastEthernet0/1    |    NULL |
| xxxxxxxxxxx   |  144315 | Fa0/0    | FastEthernet0/0    |    NULL |
| xxxxxxxxxxx   |  144316 | Fa0/1    | FastEthernet0/1    |    NULL |
| xxxxxxxxxxx   |  144442 | Et0/0    | Ethernet0/0        |    NULL |
| xxxxxxxxxxx   |  144993 | Gi0/0    | GigabitEthernet0/0 |    NULL |
| xxxxxxxxxxx   |  144994 | Gi0/1    | GigabitEthernet0/1 |    NULL |
| xxxxxxxxxxx   |  182923 | 1.1      | 1.1                |    NULL |
| xxxxxxxxxxx   |  182924 | 1.2      | 1.2                |    NULL |
| xxxxxxxxxxx   |  182928 | 1.1      | 1.1                |    NULL |
| xxxxxxxxxxx   |  182929 | 1.2      | 1.2                |    NULL |

So I modified this file /opt/librenms/app/Console/Commands/PortTune.php and changed the code.

Original:

Rrd::tune('port', $rrdfile, $port->ifSpeed);

Modified:

if ($port->ifSpeed !== null && $port->ifSpeed > 0) {
    Rrd::tune('port', $rrdfile, (int) $port->ifSpeed);
}

And after the code modification, it started working again

Before applying the changes

librenms@XXXXXX:~$ ./validate.php 
===========================================
Component | Version
--------- | -------
LibreNMS  | 26.10.2 (2026-10-21T12:24:46-03:00)
DB Schema | 2026_10_09_000000_reset_invalid_alert_schedule_behavior (409)
PHP       | 8.4.27
Python    | 3.13.5
Database  | MariaDB 11.8.6-MariaDB-0+deb13u1 from Debian
RRDTool   | 1.7.2
SNMP      | 5.9.4.pre2
===========================================

[OK]    Composer Version: 2.10.3
[OK]    Dependencies up-to-date.
[OK]    Database Connected
[OK]    Database Schema is current
[OK]    SQL Server meets minimum requirements
[OK]    lower_case_table_names is enabled
[OK]    MySQL engine is optimal
[OK]    Database and column collations are correct
[OK]    Database schema correct
[OK]    MySQL and PHP time match
[OK]    Distributed Polling setting is enabled globally
[OK]    Connected to rrdcached
[OK]    Active pollers found
[OK]    Dispatcher Service not detected
[OK]    Locks are functional
[OK]    Python poller wrapper is polling
[OK]    Redis is unavailable
[OK]    No errors found with polling frequencies.
[OK]    rrdtool version ok
[OK]    Connected to rrdcached

After applying the changes:

librenms@XXXXXXX:~$ ./validate.php 
===========================================
Component | Version
--------- | -------
LibreNMS  | 26.10.2 (2026-10-21T12:24:46-03:00)
DB Schema | 2026_10_09_000000_reset_invalid_alert_schedule_behavior (409)
PHP       | 8.4.27
Python    | 3.13.5
Database  | MariaDB 11.8.6-MariaDB-0+deb13u1 from Debian
RRDTool   | 1.7.2
SNMP      | 5.9.4.pre2
===========================================

[OK]    Composer Version: 2.10.3
[OK]    Dependencies up-to-date.
[OK]    Database Connected
[OK]    Database Schema is current
[OK]    SQL Server meets minimum requirements
[OK]    lower_case_table_names is enabled
[OK]    MySQL engine is optimal
[OK]    Database and column collations are correct
[OK]    Database schema correct
[OK]    MySQL and PHP time match
[OK]    Distributed Polling setting is enabled globally
[OK]    Connected to rrdcached
[OK]    Active pollers found
[OK]    Dispatcher Service not detected
[OK]    Locks are functional
[OK]    Python poller wrapper is polling
[OK]    Redis is unavailable
[OK]    No errors found with polling frequencies.
[OK]    rrdtool version ok
[OK]    Connected to rrdcached
[WARN]  Your local git contains modified files, this could prevent automatic updates.
        [FIX]: 
        You can fix this with ./scripts/github-remove
        Modified Files:
         app/Console/Commands/PortTune.php

Thanks,

Regards