quarkusio/quarkus · error · IllegalArgumentException

When generating a CronJob resource, you need to specify a sc

Error message

When generating a CronJob resource, you need to specify a schedule CRON expression.

What it means

When Quarkus generates a Kubernetes CronJob resource (quarkus.kubernetes.deployment-kind=CronJob), AddCronJobResourceDecorator must end up with a schedule in the CronJob spec. It applies quarkus.kubernetes.cron-job.<name>.schedule if present, then checks the resulting spec; if there is still no non-blank schedule — neither from an existing generated resource nor from config — it throws this IllegalArgumentException, because a CronJob without a schedule is invalid in Kubernetes.

Source

Thrown at extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddCronJobResourceDecorator.java:43

        // match labels for selector
        // for some reason, tests want null selector if not explicitly set
        if (jobTemplateSpec.hasSelector()) {
            initSelectorMatchLabels(jobTemplateSpec.editSelector())
                    .endSelector();
        }

        // configure job pod and container from template
        configurePodSpec(jobTemplateSpec.editOrNewTemplate().editOrNewSpec())
                .endSpec().endTemplate();

        spec.withSuspend(config.suspend());
        spec.withConcurrencyPolicy(config.concurrencyPolicy().name());

        config.schedule().ifPresent(spec::withSchedule);
        // check that we end up with a schedule, either from existing resource or configuration
        final var schedule = spec.getSchedule();
        if (schedule == null || schedule.isBlank()) {
            throw new IllegalArgumentException(
                    "When generating a CronJob resource, you need to specify a schedule CRON expression.");
        }
        config.successfulJobsHistoryLimit().ifPresent(spec::withSuccessfulJobsHistoryLimit);
        config.failedJobsHistoryLimit().ifPresent(spec::withFailedJobsHistoryLimit);
        config.startingDeadlineSeconds().ifPresent(spec::withStartingDeadlineSeconds);
        config.timeZone().ifPresent(spec::withTimeZone);

        // init job template from config
        initFromConfig(jobTemplateSpec, config);

        jobTemplateSpec.endSpec().endJobTemplate();
        spec.endSpec();
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set a CRON expression in application.properties: quarkus.kubernetes.cron-job.<name>.schedule="0 */5 * * *"
  2. Verify the schedule is under the same <name> key as your generated CronJob resource
  3. Check you didn't leave the schedule property empty or misspelled
  4. If the schedule should come from an existing resource, ensure that decorator/source actually runs before this check

Example fix

// before
quarkus.kubernetes.deployment-kind=CronJob
// after
quarkus.kubernetes.deployment-kind=CronJob
quarkus.kubernetes.cron-job.default.schedule="0 */5 * * *"
Defensive patterns

Strategy: validation

Validate before calling

// application.properties check before build
// assert properties.containsKey("quarkus.kubernetes.cron-job." + name + ".schedule") when deployment-kind=CronJob
if ("CronJob".equals(deploymentKind) && schedule == null || schedule.isBlank()) { fail("CronJob requires a schedule"); }

Try / catch

try { quarkusBuild(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("CronJob")) { /* set schedule config */ } }

Prevention

When it happens

Trigger: Building with deployment-kind CronJob (or a CronJob build item) without setting quarkus.kubernetes.cron-job.<name>.schedule (or the legacy .cron-job config), and without any pre-existing schedule in the generated spec.

Common situations: Switching an existing app from Deployment to CronJob and forgetting the schedule property; typos in the schedule property name; config applied to a different cron-job key than the generated one; schedule set to empty string.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/a9757c8111efd393. Report an issue: GitHub.