apache/beam · error · java.lang.IllegalArgumentException
stagingBucketName must end with '/'
Error message
stagingBucketName must end with '/'
What it means
The Snowflake read schema transform requires a staging bucket name that ends with a trailing slash ('/'); validate() throws IllegalArgumentException('stagingBucketName must end with \'/\'') otherwise. The bucket is used for CSV data export/import staging with Snowflake.
Solutions
- Append '/' to the bucket name: setStagingBucketName("gs://my-bucket/").
- If using a prefix, include it before the slash: 'gs://my-bucket/stage/' (the trailing slash is still required).
- Normalize the value in your config loader before constructing the configuration object.
- Check that you didn't pass the storage integration name or bucket URI with query params.
Example fix
// before
.setStagingBucketName("gs://my-bucket")
// after
.setStagingBucketName("gs://my-bucket/") Defensive patterns
Strategy: validation
Validate before calling
if (bucket != null && !bucket.endsWith("/")) {
bucket = bucket + "/"; // normalize before building configuration
} Prevention
- Always normalize stage bucket URIs to end with '/'.
- Store the bucket value already slash-terminated in config.
- Remember prefixes need the trailing slash too: gs://bucket/prefix/.
When it happens
Trigger: Configuring stagingBucketName as 'gs://my-bucket' or 'gs://my-bucket/prefix' without a trailing '/'.
Common situations: Copying a bucket URL from the cloud console (which omits the slash); building the path from variables where the prefix lacks a separator; GCS vs S3 path formats.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Could not find file
- Either table or query must be specified.
- Error constructing default value for gcpTempLocation…
- Exactly one authentication method must be configured…
- Expected a valid 'gs://' path but was given
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/945ebe9f1a6c629f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeReadSchemaTransformProvider.java:238
getOauthToken(),
getPrivateKey(),
getPrivateKeyPassphrase());
String table = getTable();
boolean tablePresent = table != null && !table.isEmpty();
String query = getQuery();
boolean queryPresent = query != null && !query.isEmpty();
if (!tablePresent && !queryPresent) {
throw new IllegalArgumentException("Either table or query must be specified.");
}
if (tablePresent && queryPresent) {
throw new IllegalArgumentException("table and query are mutually exclusive.");
}
if (!getStagingBucketName().endsWith("/")) {
throw new IllegalArgumentException("stagingBucketName must end with '/'");
}
// Validate JSON schema early.
JsonUtils.beamSchemaFromJsonSchema(getSchema());
}
private static void requireNonEmpty(String value, String name) {
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException(name + " cannot be empty");
}
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setServerName(String value);
public abstract Builder setUsername(@Nullable String value);View on GitHub (pinned to 12126d8942)