apache/pulsar · error · IllegalArgumentException
%s Package is not provided
Error message
%s Package is not provided
What it means
During sink registration via registerSink, when no package URL (sinkPkgUrl) is supplied, the worker validates that the sink's code is available somewhere: either marked as builtin in the sink config or supplied as an uploaded package (file + input stream). If the FunctionDetails are not builtin and no package file/upload was received, the worker throws IllegalArgumentException('Sink Package is not provided'), which is converted to HTTP 400.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SinksImpl.java:168
FunctionDetails functionDetails;
File componentPackageFile = null;
try {
// validate parameters
try {
if (isNotBlank(sinkPkgUrl)) {
componentPackageFile = getPackageFile(componentType, sinkPkgUrl);
functionDetails = validateUpdateRequestParams(tenant, namespace, sinkName,
sinkConfig, componentPackageFile);
} else {
if (uploadedInputStream != null) {
componentPackageFile = WorkerUtils.dumpToTmpFile(uploadedInputStream);
}
functionDetails = validateUpdateRequestParams(tenant, namespace, sinkName,
sinkConfig, componentPackageFile);
if (!isFunctionCodeBuiltin(functionDetails)
&& (componentPackageFile == null || fileDetail == null)) {
throw new IllegalArgumentException(
ComponentTypeUtils.toString(componentType) + " Package is not provided");
}
}
} catch (Exception e) {
log.error().attr("componentType", ComponentTypeUtils.toString(componentType)).attr("tenant", tenant)
.attr("namespace", namespace).attr("componentName", sinkName).exception(e)
.log("Invalid register request @ / / /");
throw new RestException(Response.Status.BAD_REQUEST, e.getMessage());
}
try {
worker().getFunctionRuntimeManager().getRuntimeFactory().doAdmissionChecks(functionDetails);
} catch (Exception e) {
log.error().attr("componentType", ComponentTypeUtils.toString(componentType)).attr("tenant", tenant)
.attr("namespace", namespace).attr("componentName", sinkName)View on GitHub (pinned to 820761864e)
Solutions
- Provide the sink archive: attach the NAR/JAR file in the multipart upload or set sinkPkgUrl to a valid http/file package URL.
- If using a bundled connector, set sinkConfig.builtin (and archive) to the builtin sink name so isFunctionCodeBuiltin passes.
- Verify the multipart part carrying the file is named correctly so fileDetail is non-null server-side.
- Check worker logs ('Invalid register request') to confirm which validation failed.
Example fix
// before: no package and no builtin
POST /admin/v3/sinks/my-tenant/my-ns/my-sink (no file part, sinkConfig.className="com.me.MySink")
// after: upload the archive
POST /admin/v3/sinks/my-tenant/my-ns/my-sink -F "url=@my-sink.nar" -F "sinkConfig={...};type=application/json"
// or use a builtin connector
sinkConfig.setBuiltin("elastic-search"); Defensive patterns
Strategy: validation
Validate before calling
boolean canRegister = cfg.getBuiltin() != null || pkgUrl != null || archiveFile != null;
if (!canRegister) throw new IllegalStateException("Provide a builtin connector or an archive (file/pkgUrl)"); Try / catch
try { admin.sinks().createSink(cfg, archive); } catch (PulsarAdminException e) { if (e.getStatusCode() == 400 && String.valueOf(e.getMessage()).contains("Package is not provided")) { /* attach archive and retry */ } else throw e; } Prevention
- Always attach the NAR/JAR or set sinkPkgUrl when className is not builtin
- Set sinkConfig.builtin for connectors bundled with the worker
- Check the multipart file part name matches what the REST endpoint expects
- Dry-run config validation in CI before hitting the admin API
When it happens
Trigger: Calling POST /admin/v3/sinks/{tenant}/{namespace}/{sinkName} without sinkPkgUrl, without an uploaded jar file body, and with a sinkConfig whose className is not a builtin connector (archive/builtin field not set to a known builtin sink).
Common situations: Client SDK calls that omit the file upload part while intending a custom sink; forgetting to set 'builtin' in SinkConfig when using a bundled connector; multipart form where fileDetail is null because the jar part name is wrong; tools that pass packageName instead of the actual archive.
Related errors
- <validation message from IllegalArgumentException>
- ${e.getMessage()}
- Only one of serdeClassName or schemaType should be set
- When effectively once processing guarantee is specified, ret
- Only one of retain ordering or retain key ordering can be se
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/63ffdaf1bffcfd47.
Report an issue: GitHub.