kubernetes/kops · error

%s is not a valid S3 URL. No bucket defined.

Error message

%s is not a valid S3 URL. No bucket defined.

What it means

VFSPath matched the S3 URL regex but captured neither a bucket nor a path. The best-known case is the bare URL 's3://' or an equivalent like 's3:///' — the scheme is right but there is no bucket to operate on, so kOps throws this error instead of building a bucket-less path.

Source

Thrown at util/pkg/vfs/s3context.go:379

func VFSPath(url string) (string, error) {
	if !s3UrlRegexp.MatchString(url) {
		return "", fmt.Errorf("%s is not a valid S3 URL", url)
	}
	groupNames := s3UrlRegexp.SubexpNames()
	result := s3UrlRegexp.FindAllStringSubmatch(url, -1)[0]

	captured := map[string]string{}
	for i, value := range result {
		if value != "" {
			captured[groupNames[i]] = value
		}
	}
	bucket := captured["bucket"]
	path := captured["path"]
	if bucket == "" {
		if path == "" {
			return "", fmt.Errorf("%s is not a valid S3 URL. No bucket defined.", url)
		}
		return fmt.Sprintf("s3:/%s", path), nil
	}
	return fmt.Sprintf("s3://%s%s", bucket, path), nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set the full store including the bucket: export KOPS_STATE_STORE=s3://<your-bucket> and re-run the command
  2. Check the variable feeding the URL is actually populated (echo "$BUCKET") — an empty expansion yields s3://
  3. In scripts, fail early: [ -n "$BUCKET" ] || { echo 'BUCKET not set'; exit 1; } before building the s3:// URL
  4. Fix templating/CI config so the state-store field is not rendered empty; use a required-input check in your pipeline

Example fix

// before: empty variable collapses the URL
kops create cluster --state "s3://${BUCKET}"
// error: s3:// is not a valid S3 URL. No bucket defined.
// after
: "${BUCKET:?BUCKET must be set}"
kops create cluster --state "s3://${BUCKET}"
Defensive patterns

Strategy: validation

Validate before calling

// Require a non-empty bucket part in the S3 URL
url="${KOPS_STATE_STORE}"
rest="${url#s3://}"
[[ "$url" == s3://* && -n "${rest%%/*}" ]] \
  || { echo "s3 URL missing bucket: $url"; exit 1; }

Type guard

func hasBucketInS3URL(url string) bool {
	if !strings.HasPrefix(url, "s3://") {
		return false
	}
	rest := strings.TrimPrefix(url, "s3://")
	bucket := rest
	if i := strings.IndexByte(rest, '/'); i >= 0 {
		bucket = rest[:i]
	}
	return bucket != ""
}

Prevention

When it happens

Trigger: VFSPath receives a URL whose regex capture groups for 'bucket' and 'path' are both empty — e.g. 's3://', 's3:///', or a URL consisting only of scheme+separators — while converting a state-store specification via buildVFSPath. (Note: 's3://<path-only>' intentionally succeeds, returning s3:/<path>.)

Common situations: KOPS_STATE_STORE set to a placeholder 's3://' in CI/CD or docs copy-paste; a variable expansion that lost the bucket name (unset $BUCKET leaving 's3://'); scripts concatenating 's3://' with an empty variable; templating tools rendering empty config values.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/b820e74ee9f239aa. Report an issue: GitHub.