apache/pulsar · error · RuntimeException

Kubernetes only admits lower case and numbers. (jobName=%s)

Error message

Kubernetes only admits lower case and numbers. (jobName=%s)

What it means

doChecks() validates the job name against VALID_POD_NAME_REGEX (RFC-1123 DNS label: lowercase alphanumerics and '-', must start/end alphanumeric). A name failing this pattern throws RuntimeException naming the offending jobName. Kubernetes rejects any pod/statefulset/service name violating this, so it fails early.

Source

Thrown at pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/kubernetes/KubernetesRuntime.java:1168

            return jobName;
        }
        // toValidPodName may cause naming collisions, add a short hash here to avoid it
        final String shortHash = DigestUtils.sha1Hex(jobNameBase).toLowerCase().substring(0, 8);
        return convertedJobName + "-" + shortHash;
    }
    @VisibleForTesting
    String getServiceUrl(String jobName, String jobNamespace, int instanceId) {
        String suffix = isNotBlank(kubernetesServiceDomainSuffix) ? kubernetesServiceDomainSuffix : "svc.cluster.local";
        return String.format("%s-%d.%s.%s.%s", jobName, instanceId, jobName, jobNamespace, suffix);
    }
    public static void doChecks(FunctionDetails functionDetails, String overridenJobName) {
        final String jobName = createJobName(functionDetails, overridenJobName);
        if (!jobName.equals(jobName.toLowerCase())) {
            throw new RuntimeException("Kubernetes does not allow upper case jobNames.");
        }
        final Matcher matcher = VALID_POD_NAME_REGEX.matcher(jobName);
        if (!matcher.matches()) {
            throw new RuntimeException("Kubernetes only admits lower case and numbers. "
                    + "(jobName=" + jobName + ")");
        }
        if (jobName.length() > maxJobNameSize) {
            throw new RuntimeException("Kubernetes job name size should be less than " + maxJobNameSize);
        }
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Rename the function to use only lowercase letters, numbers, and '-', starting and ending alphanumeric.
  2. Replace underscores/dots with hyphens in tenant/namespace/function names.
  3. If using a custom job name override, sanitize it to a valid RFC-1123 DNS label.

Example fix

// before
functions create --name my_func.v2 ...
// after
functions create --name my-func-v2 ...
Defensive patterns

Strategy: validation

Validate before calling

Pattern RFC1123 = Pattern.compile("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$");
String jobName = tenant + "-" + namespace + "-" + functionName;
if (!RFC1123.matcher(jobName).matches() || jobName.length() > 63) {
    throw new IllegalArgumentException("Job name is not a valid RFC-1123 DNS label: " + jobName);
}

Type guard

static boolean isValidDnsLabel(String s) {
    return s != null && s.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") && s.length() <= 63;
}

Try / catch

try {
    functions.create(request);
} catch (RuntimeException e) {
    if (e.getMessage().contains("only admits lower case and numbers")) {
        log.error("Replace invalid characters (underscores, dots) with hyphens: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: The composed job name contains invalid characters (underscores, dots, uppercase, leading/trailing '-', or is empty) from function tenant/namespace/name or the overridden job name.

Common situations: Function names with underscores ("my_func") or dots; names starting with a dash; overly long names (next check > maxJobNameSize); names with special characters from templating.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/76ae6d86ff4cc880. Report an issue: GitHub.