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

  1. Append '/' to the bucket name: setStagingBucketName("gs://my-bucket/").
  2. If using a prefix, include it before the slash: 'gs://my-bucket/stage/' (the trailing slash is still required).
  3. Normalize the value in your config loader before constructing the configuration object.
  4. 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

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


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)