Failed to parse calendar expression: ошибка в OnCalendar
Сообщение «Failed to parse calendar expression» означает ошибку в записи OnCalendar=. Формат отличается от cron, и привычные по crontab строки тут не работают: порядок полей другой, дни недели пишутся словами, обязателен разделитель между датой и временем.
Что это значит
Общий вид записи: ДниНедели Год-Месяц-День Час:Минута:Секунда. Любую часть можно опустить или заменить звёздочкой. Есть сокращения: daily, weekly, monthly, hourly, minutely. Проверять запись нужно командой systemd-analyze calendar, а не перезапуском таймера.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Использован формат crontab
Запись вида
0 3 * * *для systemd бессмысленна: он ждёт дату и время, а не пять полей cron. -
Неверные имена дней недели или разделители
Дни недели пишутся сокращениями (
Mon,Tue,Wed), перечисляются через запятую, диапазон — через двойную точку:Mon..Fri. Русские названия и другие разделители не разбираются. -
Недопустимые значения времени
Час больше 23, минута больше 59, 31-е число в месяце, где его нет. Часть таких записей разбирается, но срабатывания не происходит никогда.
-
Забыт разделитель между датой и временем
Запись
*-*-*03:00:00без пробела не разбирается, и ошибка в глаза не бросается.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Разбирает запись и печатает нормализованный вид с ближайшими срабатываниями. Основной инструмент для этой ошибки.
systemd-analyze calendar "ваше выражение"Показывает, какие выражения systemd фактически принял.
systemctl show myapp.timer -p TimersCalendarСообщение о неудачном разборе с номером строки unit-файла.
journalctl -u myapp.timer -n 20 --no-pagerРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Запись вида
0 3 * * *для systemd бессмысленна: он ждёт дату и время, а не пять полей cron.
- Как проверить
-
Разберите выражение отдельной командой.
systemd-analyze calendar "0 3 * * *"
- Как исправить
-
Перепишите в формате systemd: ежедневно в три часа ночи — это
OnCalendar=*-*-* 03:00:00или корочеOnCalendar=dailyсо сдвигом.OnCalendar=*-*-* 03:00:00
- Почему происходит
- Дни недели пишутся сокращениями (
Mon,Tue,Wed), перечисляются через запятую, диапазон — через двойную точку:Mon..Fri. Русские названия и другие разделители не разбираются.
- Как проверить
-
Проверьте запись.
systemd-analyze calendar "Mon..Fri 09:00"
- Как исправить
- Приведите дни недели к принятым сокращениям. Проверка печатает разбор и ближайшее срабатывание — по нему видно, что systemd понял.
- Почему происходит
- Час больше 23, минута больше 59, 31-е число в месяце, где его нет. Часть таких записей разбирается, но срабатывания не происходит никогда.
- Как проверить
-
Посмотрите, что печатает разбор: при отсутствии подходящего момента он честно об этом скажет.
systemd-analyze calendar "*-02-30 03:00:00"
- Как исправить
-
Исправьте значения. Для «последнего дня месяца» есть особая запись:
*-*~01.
- Почему происходит
- Запись
*-*-*03:00:00без пробела не разбирается, и ошибка в глаза не бросается.
- Как проверить
-
Проверьте запись целиком, включая пробелы.
systemctl show myapp.timer -p TimersCalendar
- Как исправить
- Поставьте пробел между датой и временем.
Пример вывода
Попытка задать расписание в формате cron. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ systemd-analyze calendar "0 3 * * *"
Failed to parse calendar expression '0 3 * * *': Invalid argument
systemd[1]: /etc/systemd/system/myapp.timer:5: Failed to parse calendar specification, ignoring: 0 3 * * *
systemd[1]: myapp.timer: Refusing to start, unit has no trigger.
Связанные ошибки
- Таймер активен, но не срабатывает Таймер systemd в состоянии active, но служба не запускается. Разбор: нет условия срабатывания, таймер не включён, ошибка в OnCalendar.
- Unit file is bad и ошибки разбора unit-файла systemd не может разобрать unit-файл: неизвестные параметры, ошибки в секциях, недопустимые значения. Как найти проблемную строку.
- Два таймера на одну службу: срабатывания накладываются Одна служба вызывается несколькими таймерами: запуски накладываются, часть срабатываний теряется.
- Задача cron не выполняется Задача в crontab не запускается: короткий PATH, права на файл задачи, точка в имени файла, отсутствие перевода строки.
- Пропущенное срабатывание таймера: Persistent и выключенная машина Таймер не выполнил задачу, потому что в момент срабатывания машина была выключена или служба была недоступна. Как работает Persistent=true.
- A start job is running: загрузка висит на одной службе Загрузка останавливается с обратным отсчётом: служба не укладывается в таймаут. Как найти виновника и не ждать.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Apache: Invalid command — не включён модуль Apache не запускается: директива требует модуль, который не подключён. Как найти нужный модуль и включить.
Источники
-
systemd.time(7)
Полный формат календарных выражений и сокращения. -
systemd-analyze(1)
Команда calendar: разбор и проверка расписаний. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на записи в формате crontab: systemd-analyze calendar отказывается её разбирать.