Skip to main content

Jenkins cron - last day of the month

At 04:30, every day.

Next runs · UTC

Calendar

September 2026 · UTC

0 runs

About this tool

Jenkins cron does not support the L modifier. To trigger a Jenkins build on the last day of every month, use the multi-cron pattern across three trigger lines, or schedule daily and skip the build in a pipeline when block.
See the full Jenkins cron guide for the syntax (including the H hash modifier), or the cross-library last-day-of-month guide for the equivalent in other schedulers.

Multi-cron trigger pattern (Pipeline)

In a declarative pipeline, the triggers directive accepts multiple cron lines. Each line is a separate trigger; Jenkins fires whichever matches the current time.

groovy
pipeline {
  agent any
  triggers {
    cron('''
      0 0 30 4,6,9,11 *
      0 0 31 1,3,5,7,8,10,12 *
      0 0 28 2 *
    ''')
  }
  stages {
    stage('Month-end') {
      steps {
        // ... your last-day-of-month work
      }
    }
  }
}

The triple-quoted string is parsed line-by-line. The Feb 28 line covers non-leap years; for leap-year-safe handling, add a fourth line for Feb 29 plus a runtime check.

Daily trigger + runtime skip

A simpler alternative: schedule daily and use a when block to skip non-last-day builds.

groovy
pipeline {
  agent any
  triggers {
    cron('H 0 * * *')   // daily at a stable minute past midnight
  }
  stages {
    stage('Month-end work') {
      when {
        expression {
          // True when tomorrow is the 1st (i.e. today is the last day).
          return sh(returnStdout: true, script: "date -d tomorrow +%d").trim() == "01"
        }
      }
      steps {
        // ... your last-day-of-month work
      }
    }
  }
}

The H 0 * * * cron uses the Jenkins H modifier in the minute field - Jenkins picks a stable minute based on the job name hash so the build fires at, say, 00:17 every day instead of 00:00 sharp.

Freestyle job configuration

For a Freestyle job (non-pipeline), enter the multi-cron expression in the “Build periodically” box:

crontab
# Run on the last day of every month at midnight
0 0 30 4,6,9,11 *
0 0 31 1,3,5,7,8,10,12 *
0 0 28 2 *

Comments (lines starting with #) are accepted in the trigger field - useful for documenting complex multi-cron setups in place.

Jenkins-specific pitfalls

  • SCM polling - if your job triggers on SCM changes too, the build will fire whenever code is pushed, regardless of date. Use the when block to gate the actual work.
  • Build queueing - Jenkins can't run two instances of the same job concurrently by default. If your last-day job runs long, the next month's trigger may queue.
  • Timezone - Jenkins cron honours the controller's JVM timezone by default. For UTC, set the JVM property -Dorg.apache.commons.jelly.tags.fmt.timeZone=UTC or use a per-trigger TZ prefix.

Examples

  • 0 18 * * *
    Every day at 18:00
  • 0 */5 * * *
    Every 5 hours
  • 0 18 * * 1-5
    Weekdays at 18:00
  • 0 0 1 * *
    Once a month, on the 1st at midnight

Cheatsheet

Full cheatsheet
FieldReq.RangeWildcards
minuteyes0-59, - * /
houryes0-23, - * /
day of monthyes1-31, - * /
monthyes1-12 or JAN-DEC, - * /
day of weekyes0-6 or names; some dialects use 0-7 or 1-7 — see Dialects, - * /

Frequently asked questions

Syntax

What does the H modifier do in Jenkins cron?

H chooses a stable hash-derived field value to spread Jenkins load. For month-end, H 0 * * * can stagger the daily check, but H cannot identify the last day; runtime date logic still decides whether the work runs.

Jenkins H guide
Do Jenkins day-field semantics create a portable first-week workaround?

No. Jenkins ANDs restricted day fields, unlike Vixie cron's OR behavior, so copied day-of-month and day-of-week combinations can change meaning.

Dialect day rules

Timing

What is the simplest Jenkins month-end schedule?

Trigger daily with H 0 * * *, then gate the month-end stage with LocalDate.now(zone).plusDays(1).dayOfMonth == 1. This handles every month length with one schedule.

Daily check example

Days and months

Does Jenkins cron support the L modifier for last day of the month?

No. Jenkins supports five cron fields and H, but not L or LW. Trigger daily and gate the month-end work at runtime by checking whether tomorrow is in the next month; this handles February and leap years safely.

Operator matrix
Which Jenkins cron covers 30-day month ends?

Use 0 0 30 4,6,9,11 * for midnight on April 30, June 30, September 30, and November 30. Expression: 0 0 30 4,6,9,11 *

Open in editor
Multi-trigger pattern
Which Jenkins cron covers 31-day month ends?

Use 0 0 31 1,3,5,7,8,10,12 * for midnight on the final day of every 31-day month. Expression: 0 0 31 1,3,5,7,8,10,12 *

Open in editor
Multi-trigger pattern
How should Jenkins handle February month-end?

A fixed February 28 trigger is not leap-year safe by itself. Prefer a daily trigger plus a tomorrow-is-the-first runtime check so February 28 or 29 is selected correctly.

Runtime check pattern
Can Jenkins use LW for the last weekday?

No. Jenkins does not support L or W; use a daily trigger and evaluate the month boundary and weekday in pipeline code.

Operator matrix

Timezones and DST

What timezone does Jenkins cron use?

By default, the JVM timezone of the Jenkins controller. Set the timezone explicitly with the TZ parameter prefix: TZ=America/New_York on a line above the trigger. Jenkins 2.293+ also supports per-trigger timezone via the cronTrigger plugin.

Timezone reference
Can DST affect a Jenkins midnight month-end job?

The configured controller or trigger timezone determines the local date boundary. Set the timezone explicitly and verify its daylight-saving behavior for local schedules.

DST reference

Platforms

How do I use multiple cron triggers in a Jenkins pipeline?

The triggers { cron('...') } block accepts a multi-line string, with each line acting as a separate trigger. Do not model all month ends with fixed dates because February varies; use one daily trigger and a runtime month-boundary gate.

Multi-trigger example
Can a Jenkins Freestyle job use the month-end workaround?

Yes. Configure a daily Build periodically trigger, then make an early build step check whether tomorrow enters the next month and exit successfully on other dates. Fixed month-length lines are not leap-year safe.

Freestyle example

Debugging

How do I skip a Jenkins build that's not on the last day?

Use a stage when expression with LocalDate.now(zone).plusDays(1).dayOfMonth == 1. A false result skips that stage without failing the build; calling error() would mark the build as failed.

Runtime skip example
Why did a Jenkins month-end build run on the wrong date?

Compare the controller timezone with the timezone used by the runtime date check. The cron trigger and shell command must agree on which local date is current.

Jenkins pitfalls

Crontap

Can Crontap invoke a Jenkins endpoint at month-end?

Yes. Configure the Jenkins HTTP endpoint, authentication, a month-end schedule, and the intended IANA timezone in Crontap.

Schedule API calls

Write the cron here. Run it on Crontap.

Point Crontap at any URL. Pick any cron. Done.

WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.

1.9k+ teams · Free forever tier · No credit card