API Call: device_maintenance returns always "Error, Duration not provided"

Hello community,

At the moment, I have some difficulties with API. I want to set devices into Maintenance Mode per API call based on: https://docs.librenms.org/API/Devices/#maintenance_device

My example API call looks like this:

~$ curl -k -H 'X-Auth-Token: 12345' \
-X POST https://librenms.example.com/api/v0/devices/server1.example.com/maintenance/  \
 --data-raw '{"duration":"2:00",}'

And I’m always getting as result:

{
    "status": "error",
    "message": "Duration not provided"
}

Version:

[25.4.0-64-g08451a2ba - Thu May 01 2025 23:33:05 GMT+0200](https://www.librenms.org/changelog.html)

If I remember correctly, the API call was working with an older version from about one or two weeks ago. Eventually someone might have an idea or can point me into the correct direction?

Last Date/Time working was on 2025-04-19:

Thank you

Odd request here, but if you both provide some notes in your request AND set the duration to “0:00” does it work?

"notes":"notes","duration":"0:00"

It’s pretty old code, and the error handling isn’t perfect - so it’s not being entirely honest about where it’s failing.

On one box I have I’m seeing 2 issues:

  1. "message": "SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'notes' cannot be null - don’t know when that become a thing, but it seems it is now.
  2. "message": "Carbon\\Carbon::rawAddUnit(): Argument #3 ($value) must be of type int|float, string given, called in /opt/librenms/vendor/nesbot/carbon/src/Carbon/Traits/Units.php on line 356" which may be related to the Laravel 11.x move that could have pulled in Carbon 3, which had breaking changes from what I’ve just read. I don’t know how to refactor to fix those.

On older installs before the Laravel uplifts, just adding notes works.

Edit … OK turns out you can easily make it work by casting the user input to float, and mandating notes in the checks. I’ll try and get a PR together to fix it.

--- a/includes/html/api_functions.inc.php
+++ b/includes/html/api_functions.inc.php
@@ -517,7 +517,7 @@ function maintenance_device(Illuminate\Http\Request $request)
         return api_error(400, 'Duration not provided');
     }

-    $notes = $request->json('notes');
+    empty($request->json('notes')) ? $notes = '' : $notes = $request->json('notes');
     $title = $request->json('title') ?? $device->displayName();
     $alert_schedule = new \App\Models\AlertSchedule([
         'title' => $title,
@@ -533,7 +533,7 @@ function maintenance_device(Illuminate\Http\Request $request)
     if (Str::contains($duration, ':')) {
         [$duration_hour, $duration_min] = explode(':', $duration);
         $alert_schedule->end = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $start)
-            ->addHours($duration_hour)->addMinutes($duration_min)
+            ->addHours((float)$duration_hour)->addMinutes((float)$duration_min)
             ->format('Y-m-d H:i:00');
     }

@@ -2530,7 +2530,7 @@ function maintenance_devicegroup(Illuminate\Http\Request $request)
         return api_error(400, 'Duration not provided');
     }

-    $notes = $request->json('notes');
+    empty($request->json('notes')) ? $notes = '' : $notes = $request->json('notes');
     $title = $request->json('title') ?? $device_group->name;

     $alert_schedule = new \App\Models\AlertSchedule([
@@ -2547,7 +2547,7 @@ function maintenance_devicegroup(Illuminate\Http\Request $request)
     if (Str::contains($duration, ':')) {
         [$duration_hour, $duration_min] = explode(':', $duration);
         $alert_schedule->end = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $start)
-            ->addHours($duration_hour)->addMinutes($duration_min)
+            ->addHours((float)$duration_hour)->addMinutes((float)$duration_min)
             ->format('Y-m-d H:i:00');
     }

Give this a try Fix API maintenance call notes and duration parsing by rhinoau · Pull Request #17583 · librenms/librenms · GitHub

Hi,
Thank you for the quick response.

I tried with

--data-raw '{"notes":"test","duration":"0:00",}'

same error, Duration not provided.

I’ll try the fix in the afternoon on my test installation. I’m not an expert in PHP Laravel, but input validation makes sense for me here.

Drop the trailing comma from your data and see if any different - I’ve dealt with that error handling in the change too - it would throw back “No information has been provided to set this device into maintenance” with that input.

Applied patch, here is the result:

~$ curl -k -H 'X-Auth-Token: 1234'   -X POST https://librenms.example.com/api/v0/devices/server1.example.com/maintenance/   --data-raw '{"notes":"test","duration":"1:00"}'
{
    "status": "ok",
    "message": "Device server1.example.com (114) moved into maintenance mode for 1:00h"
}

Works perfectly, Device is in Maintenance for 1 hour.

API Call with Ansible role/playbook works as well.

Thank you :+1:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.