kubernetes/kops · error
invalid S3 location
Error message
invalid S3 location
What it means
escapeS3Location requires the parsed URL to have exactly the scheme 's3' and a non-empty host (the bucket name). If either check fails, it returns this error because an S3 path without a bucket, or with the wrong scheme, cannot be resolved later.
Source
Thrown at pkg/model/resources/nodeup.go:289
default:
continue
}
escaped, err := escape(location)
if err != nil {
return "", fmt.Errorf("escaping nodeup source %q: %w", location, err)
}
locations[i] = escaped
}
return strings.Join(locations, ","), nil
}
func escapeS3Location(location string) (string, error) {
u, err := url.Parse(location)
if err != nil {
return "", fmt.Errorf("parsing S3 location: %w", err)
}
if u.Scheme != "s3" || u.Host == "" {
return "", fmt.Errorf("invalid S3 location")
}
return "s3://" + u.Host + httpbinding.EscapePath(u.Path, false), nil
}
func escapeBlobLocation(location string) (string, error) {
u, err := url.Parse(location)
if err != nil {
return "", fmt.Errorf("parsing Azure Blob location: %w", err)
}
container, key, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
// Reject ports, IPv6 hosts, userinfo, queries, and fragments, which the account-based
// blob.core.windows.net URL cannot represent, so they fail here instead of in the boot retry loop.
if u.Scheme != "azureblob" || u.Host == "" || u.Hostname() != u.Host || u.User != nil || u.RawQuery != "" || u.Fragment != "" || container == "" || key == "" {
return "", fmt.Errorf("invalid Azure Blob location; expected azureblob://<account>/<container>/<key>")
}
return "azureblob://" + u.Host + httpbinding.EscapePath(u.Path, false), nilView on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the location starts with exactly s3:// (lowercase) and includes a bucket: s3://bucket/key.
- Check for double slashes or a missing bucket after the scheme prefix.
- If the bucket is filled from config/flag input, validate it is non-empty before building the source string.
- Rebuild the nodeup script after fixing the URL.
Example fix
// before NodeUpSource: "s3:///artifacts/nodeup" // after NodeUpSource: "s3://my-artifacts-bucket/artifacts/nodeup"
Defensive patterns
Strategy: validation
Validate before calling
u, _ := url.Parse(location)
if u.Scheme != "s3" || u.Host == "" {
return errors.New("location must be s3://<bucket>/<key>")
} Type guard
func isS3Location(loc string) bool {
u, err := url.Parse(loc)
return err == nil && u.Scheme == "s3" && u.Host != ""
} Try / catch
if !isS3Location(loc) {
return fmt.Errorf("%q must include bucket: s3://bucket/key", loc)
} Prevention
- Always include the bucket in s3:// URLs (never s3:///path)
- Use lowercase s3 scheme exactly
- Add config linting that checks source URL schemes
When it happens
Trigger: A nodeup source location whose scheme is not exactly 's3' (e.g. 'S3://', 'https://', empty) or which parses with an empty host, e.g. 's3:///path/to/nodeup' or 's3://'.
Common situations: Bucket name accidentally dropped during refactoring, using an https URL where an s3:// URL is required, or a bare path like '/path/to/nodeup' passed as a source.
Related errors
- error reading etcd manifest %s: %v
- challenge not set
- challenge.id not set
- parsing S3 location: %w
- invalid Azure Blob location; expected azureblob://<account>/
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/26cedbe00018b8bd.
Report an issue: GitHub.