kubernetes/kops · error

invalid spaces path: %q

Error message

invalid spaces path: %q

What it means

buildDOPath failed to parse the given path as a URL. DigitalOcean Spaces locations must be parseable do://bucket/key URLs; when url.Parse returns an error, the path is rejected with this message.

Source

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

			o.BaseEndpoint = aws.String(endpoint)
			o.UsePathStyle = true
			o.DisableLogOutputChecksumValidationSkipped = true
		} else {
			o.EndpointResolverV2 = &ResolverV2{}
		}
	})
	return s3path, nil
}

func (c *VFSContext) buildDOPath(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 spaces path: %q", p)
	}
	if u.Scheme != "do" {
		return nil, fmt.Errorf("invalid spaces path: %q", p)
	}

	bucket := strings.TrimSuffix(u.Host, "/")
	if bucket == "" {
		return nil, fmt.Errorf("invalid spaces 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
	})
	return s3path, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the quoted path in the error; 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 do://my-space/clusters.

Example fix

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

Strategy: validation

Validate before calling

func validDOStorePath(p string) bool {
	u, err := url.Parse(p)
	return err == nil && u.Scheme == "do" && strings.TrimSuffix(u.Host, "/") != ""
}
if !validDOStorePath(os.Getenv("KOPS_STATE_STORE")) {
	return fmt.Errorf("KOPS_STATE_STORE must be a valid do://space/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 spaces path") {
		return fmt.Errorf("malformed Spaces path %q: %w", raw, err)
	}
	return err
}

Prevention

When it happens

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

Common situations: Spaces store path built by templating/shell interpolation that injects malformed characters; copy-paste introducing stray bytes into 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/6dac5bc691752b72. Report an issue: GitHub.