apache/pulsar · error · IllegalArgumentException
Per instance cpu requested, %s, for function should be posit
Error message
Per instance cpu requested, %s, for function should be positive and a multiple of the granularity, %s
What it means
KubernetesRuntimeFactory.validateResourcesGranularityAndProportion enforces that a function's requested CPU is positive and an exact multiple of the configured CPU granularity (functionInstanceResourceGranularity). The check converts both values to milli-cores to avoid floating-point loss of precision; if cpuMillis is 0 or cpuMillis % grnCpuMillis != 0, admission is rejected with this IllegalArgumentException during doAdmissionChecks.
Source
Thrown at pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/kubernetes/KubernetesRuntimeFactory.java:508
"Per instance RAM requested, %s, for function is greater than the maximum required, %s",
functionDetails.getResources().getRam(), maxRam));
}
}
}
void validateResourcesGranularityAndProportion(FunctionDetails functionDetails) {
final long baseMillis = 1000;
long multiples = 0L;
if (functionInstanceResourceGranularities != null) {
Double grnCpu = functionInstanceResourceGranularities.getCpu();
Long grnRam = functionInstanceResourceGranularities.getRam();
if (grnCpu != null) {
// convert cpus to milli-cores to avoid loss of precision
long grnCpuMillis = Math.round(baseMillis * grnCpu);
if (grnCpuMillis > 0) {
long cpuMillis = Math.round(baseMillis * functionDetails.getResources().getCpu());
if (cpuMillis == 0 || cpuMillis % grnCpuMillis != 0) {
throw new IllegalArgumentException(
String.format("Per instance cpu requested, %s, for function should be positive and a "
+ "multiple of the granularity, %s",
functionDetails.getResources().getCpu(), grnCpu));
}
if (functionInstanceResourceChangeInLockStep) {
multiples = cpuMillis / grnCpuMillis;
}
}
}
if (grnRam != null && grnRam > 0) {
if (functionDetails.getResources().getRam() == 0
|| functionDetails.getResources().getRam() % grnRam != 0) {
throw new IllegalArgumentException(
String.format("Per instance ram requested, %s, "
+ "for function should be positive and a multiple of the granularity, %s",
functionDetails.getResources().getRam(), grnRam));
}
if (functionInstanceResourceChangeInLockStep && multiples > 0) {View on GitHub (pinned to 820761864e)
Solutions
- Set the function's resources.cpu to a positive value that is an exact multiple of the configured CPU granularity (e.g. granularity 0.5 -> use 0.5, 1.0, 1.5).
- If no granularity constraint is desired, unset/disable functionInstanceResourceGranularity in the worker config instead of fighting the modulo check.
- If resources were omitted, explicitly configure resources (cpu and ram) on the function manifest before submission.
- If functionInstanceResourceChangeInLockStep is enabled, also ensure the cpu multiple equals the ram multiple to avoid the follow-on error 1342.
Example fix
// before (granularity = 0.5) resources: cpu: 0.35 // after resources: cpu: 0.5
Defensive patterns
Strategy: validation
Validate before calling
long granularityMillis = Math.round(1000 * configuredCpuGranularity); // e.g. 0.5 -> 500
long cpuMillis = Math.round(1000 * functionDetails.getResources().getCpu());
if (cpuMillis <= 0 || cpuMillis % granularityMillis != 0) {
throw new IllegalArgumentException("cpu must be positive and a multiple of " + configuredCpuGranularity);
} Type guard
boolean isValidCpu(Double cpu, double granularity) {
if (cpu == null || granularity <= 0) return false;
long cpuMillis = Math.round(1000 * cpu);
long grnMillis = Math.round(1000 * granularity);
return cpuMillis > 0 && cpuMillis % grnMillis == 0;
} Prevention
- Read the worker's functionInstanceResourceGranularity setting before sizing function resources.
- Always set both cpu and ram explicitly on function manifests.
- Keep cpu/ram values on granularity boundaries to survive lock-step checks.
When it happens
Trigger: Submitting/updating a function (doAdmissionChecks) to a Kubernetes runtime where pulsar.functions.functionInstanceResourceGranularity sets a CPU granularity and FunctionDetails.getResources().getCpu() is 0, negative, or not an exact multiple of that granularity.
Common situations: Tenant submits cpu=0.35 with granularity 0.5; resources left unset so cpu=0 while a granularity is configured; CPU set in cores while granularity is expressed in fractional values whose milli-core rounding makes the modulo fail (e.g. 0.1*1000 rounding issues); migrating functions from a cluster without granularity limits to one with them.
Related errors
- Per instance ram requested, %s, for function should be posit
- Per instance cpu requested, %s, ram requested, %s, for funct
- Function runtime customizer %s must implement KubernetesMani
- KubernetesSecretsProviderConfigurator should only be setup f
- UNSUPPORTED_ISSUER
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/67065c7c767297e8.
Report an issue: GitHub.