GoogleContainerTools/skaffold · error
failed creating Google Cloud Storage cache directory for %q:
Error message
failed creating Google Cloud Storage cache directory for %q: %w
What it means
Skaffold caches remote Google Cloud Storage objects under a per-source hashed subdirectory of the remote cache dir. SyncObjects creates that subdirectory with os.MkdirAll(0700) before gsutil/client downloads into it; if the OS cannot create it, the underlying error (permissions, non-directory in path, disk full, invalid path characters) is wrapped with this message.
Source
Thrown at pkg/skaffold/gcs/gsutil.go:100
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() {
return cacheDir, nil
}
}
gcs := GetGCSClient()
if err := gcs.DownloadRecursive(ctx, g.Source, cacheDir); err != nil {
return "", fmt.Errorf("failed to cache Google Cloud Storage objects from %q: %w", g.Source, err)
}
return cacheDir, nil
}View on GitHub (pinned to a1189de023)
Solutions
- Check permissions on the remote cache directory (default under ~/.config/skaffold) and the failing subdirectory; chown/chmod so the current user can write (0700).
- If a regular file occupies the cacheDir path, delete it so the directory can be recreated.
- Set a writable custom cache location via --remote-cache-dir, or free disk space if the disk is full.
- Clear the entire remote cache directory and re-run so skaffold recreates it from scratch.
Example fix
# before $ ls -l ~/.config/skaffold/cache/remote -rw-r--r-- 1 root root cache-dir # stale file blocks mkdir # after $ sudo rm -rf ~/.config/skaffold/cache/remote/cache-dir $ sudo chown -R $USER ~/.config/skaffold/cache/remote
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(cacheDir); err == nil {
if info, ok := err.(nil); !ok { /* stat succeeded */ }
}
// pre-check writability of the parent cache dir before calling SyncObjects
if fi, err := os.Stat(parentDir); err != nil || !fi.IsDir() || fi.Mode().Perm()&0200 == 0 {
return fmt.Errorf("cache dir %s not writable: %v", parentDir, err)
} Type guard
func isPathError(err error) (*os.PathError, bool) {
var pe *os.PathError
if errors.As(err, &pe) {
return pe, true
}
return nil, false
} Try / catch
cacheDir, err := gcs.SyncObjects(ctx, gcsInfo, opts)
if err != nil {
var pe *os.PathError
if errors.As(err, &pe) && os.IsPermission(pe.Err) {
log.Warnf("fix permissions on %s: %v", pe.Path, pe.Err)
return retryWithNewCacheDir(ctx, "--remote-cache-dir", "/tmp/skaffold-cache")
}
return err
} Prevention
- Run skaffold as a user that owns the remote cache directory; avoid mixing root and user runs.
- Add a startup check that the --remote-cache-dir (or its default) exists, is a directory, and is writable.
- Never store non-directory files inside the cache path tree.
- Monitor disk space in CI; provision the cache on a writable volume.
When it happens
Trigger: Calling SyncObjects (directly or via cacheGCSObject) for a GCS source whose cache subdirectory does not exist, while os.MkdirAll(cacheDir, 0700) fails — e.g. parent remote cache dir is read-only, a file exists where the directory should be, or the path is invalid.
Common situations: Running skaffold as a non-root user against a cache dir created by root; ~/.config/skaffold or a custom --remote-cache-dir on a read-only mount or full disk; stale cache dir replaced by a regular file; NFS/CI containers with restrictive umasks.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- failed to create directory: %v
- failed to create file: %v
- failed creating remote cache directory: %w
- initializing cache: %w
- CONFIG_REMOTE_REPO_CACHE_NOT_FOUND_ERR
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/127cc8df7ca43f29.
Report an issue: GitHub.