kubernetes/kops · error

invalid Linode object storage path: %q

Error message

invalid Linode object storage path: %q

What it means

buildLinodePath failed to parse the given path as a URL. Linode Object Storage locations must be parseable linode://bucket/key URLs; when url.Parse errors, the path is rejected with this message.

Source

Thrown at util/pkg/vfs/context.go:407

	}

	s3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {
		o.BaseEndpoint = aws.String(endpoint)
		o.UsePathStyle = true
		o.DisableLogOutputChecksumValidationSkipped = true
	})
	return s3path, nil
}

func (c *VFSContext) buildLinodePath(p string) (*S3Path, error) {
	endpoint := os.Getenv("S3_ENDPOINT")
	if endpoint == "" {
		return nil, fmt.Errorf("required S3_ENDPOINT env var for path: %q", p)
	}

	u, err := url.Parse(p)
	if err != nil {
		return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
	}
	if u.Scheme != "linode" {
		return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
	}

	bucket := strings.TrimSuffix(u.Host, "/")
	if bucket == "" {
		return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
	}

	s3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {
		o.BaseEndpoint = aws.String(endpoint)
		o.UsePathStyle = true
		o.DisableLogOutputChecksumValidationSkipped = true
		// Akamai (Linode) requires checksum-when-required behavior
		o.RequestChecksumCalculation = aws.RequestChecksumCalculationWhenRequired
		o.ResponseChecksumValidation = aws.ResponseChecksumValidationWhenRequired
	})

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the quoted path in the error and remove or percent-encode invalid characters.
  2. Use url.PathEscape for dynamic bucket/key segments when composing the path.
  3. Set KOPS_STATE_STORE to a clean literal like linode://my-bucket/clusters.

Example fix

// before
statePath := fmt.Sprintf("linode://%s/state", taintedName)
// after
statePath := "linode://" + url.PathEscape(name) + "/state"
Defensive patterns

Strategy: validation

Validate before calling

func validLinodeStorePath(p string) bool {
	u, err := url.Parse(p)
	return err == nil && u.Scheme == "linode" && strings.TrimSuffix(u.Host, "/") != ""
}
if !validLinodeStorePath(os.Getenv("KOPS_STATE_STORE")) {
	return fmt.Errorf("KOPS_STATE_STORE must be a valid linode://bucket/path URL, got %q", os.Getenv("KOPS_STATE_STORE"))
}

Type guard

func isParsableURL(p string) bool {
	_, err := url.Parse(p)
	return err == nil
}

Try / catch

p, err := vfs.Context.BuildVfsPath(raw)
if err != nil {
	if strings.Contains(err.Error(), "invalid Linode object storage path") {
		return fmt.Errorf("malformed Linode path %q: %w", raw, err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling BuildVfsPath with a linode:// string that url.Parse rejects — invalid percent-escapes (linode://bucket/%zz), control characters, or unescaped non-ASCII bytes in bucket/key.

Common situations: Store path assembled by templating that injects malformed characters; copy-paste artifacts in KOPS_STATE_STORE.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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