GoogleContainerTools/skaffold · error
failed determining Google Cloud Storage remote cache directo
Error message
failed determining Google Cloud Storage remote cache directory for %q: %w
What it means
SyncObjects wraps a failure from getPerSourceDir(g), which derives the per-source subdirectory name from the configured GCS source (g.Source). If the source string cannot be parsed/normalized into a cache directory component, syncing cannot proceed. The %q verb logs the offending source value and %w preserves the cause.
Source
Thrown at pkg/skaffold/gcs/gsutil.go:90
type gscClient interface {
// Downloads the content that match the given src uri and subfolders.
DownloadRecursive(ctx context.Context, src, dst string) error
}
// SyncObjects syncs the target Google Cloud Storage objects with skaffold's local cache and returns the local path to the objects.
func SyncObjects(ctx context.Context, g latest.GoogleCloudStorageInfo, opts config.SkaffoldOptions) (string, error) {
remoteCacheDir, err := config.GetRemoteCacheDir(opts)
if err != nil {
return "", fmt.Errorf("failed determining remote cache directory: %w", err)
}
if err := os.MkdirAll(remoteCacheDir, 0700); err != nil {
return "", fmt.Errorf("failed creating remote cache directory: %w", err)
}
sourceDir, err := getPerSourceDir(g)
if err != nil {
return "", fmt.Errorf("failed determining Google Cloud Storage remote cache directory for %q: %w", g.Source, err)
}
cacheDir := filepath.Join(remoteCacheDir, sourceDir)
if _, err := os.Stat(cacheDir); os.IsNotExist(err) {
// If cache doesn't exist and cloning is disabled then we can't move forward.
if opts.SyncRemoteCache.CloneDisabled() {
return "", syncDisabledErr(g, cacheDir)
}
// The subdirectory needs to exist to work with gsutil.
if err := os.MkdirAll(cacheDir, 0700); err != nil {
return "", fmt.Errorf("failed creating Google Cloud Storage cache directory for %q: %w", g.Source, err)
}
} else {
// If sync property is false then skip fetching latest object from remote storage.
if g.Sync != nil && !*g.Sync {
return cacheDir, nil
}
// If sync is turned off via flag `--sync-remote-cache` then skip fetching latest object from remote storage.
if opts.SyncRemoteCache.FetchDisabled() {View on GitHub (pinned to a1189de023)
Solutions
- Inspect the quoted %q value in the error to see what Source was actually configured
- Fix the Source in skaffold.yaml to a valid gs:// bucket/path URL
- Ensure the Source field is non-empty and matches the schema of your skaffold version
- Test the URL with `gsutil ls <source>` to confirm it is a valid GCS path
Example fix
// before
gcs:
cache:
source: "storage.googleapis.com/my-bucket"
// after
gcs:
cache:
source: "gs://my-bucket/path" Defensive patterns
Strategy: validation
Validate before calling
// validate the GCS source before calling SyncObjects
if gcsInfo.Source == "" {
return errors.New("gcs.cache.source must be set in skaffold.yaml")
}
if !strings.HasPrefix(gcsInfo.Source, "gs://") {
return fmt.Errorf("gcs source must start with gs://, got %q", gcsInfo.Source)
} Type guard
func isValidGCSSource(src string) bool {
u, err := url.Parse(src)
return err == nil && u.Scheme == "gs" && strings.TrimPrefix(u.Path, "/") != ""
} Try / catch
localPath, err := gcs.SyncObjects(ctx, gcsInfo, opts)
if err != nil {
if strings.Contains(err.Error(), "failed determining Google Cloud Storage remote cache directory") {
log.Errorf("check gcs cache 'source' value in skaffold.yaml (got %q)", gcsInfo.Source)
}
return err
} Prevention
- Always specify source as a full gs://bucket/path URL in skaffold.yaml
- Never leave the gcs cache source field empty when sync is enabled
- Validate the source exists with `gsutil ls` before syncing
- Keep the Source field format consistent with your skaffold version's docs
- Enable --verbosity=debug to see the exact parsed value
When it happens
Trigger: Calling SyncObjects with a GoogleCloudStorageInfo.Source that getPerSourceDir cannot handle: empty Source, malformed gs:// URL, or a source form the function's parsing doesn't expect.
Common situations: skaffold.yaml gcs.cache.syncSource / source field left empty or misspelled; hand-edited gs:// URL with typos or extra path segments; config schema differences across skaffold versions changing what Source should contain.
Related errors
- failed determining remote cache directory: %w
- bucket name is empty
- CONFIG_REMOTE_REPO_CACHE_NOT_FOUND_ERR
- error closing GCS writer: %w
- copy file(s) with %s failed: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/43dde8c1bcfbd2b9.
Report an issue: GitHub.