GoogleContainerTools/skaffold · error
getting hash for %q: %w
Error message
getting hash for %q: %w
What it means
The inputDigest Tagger hashes the artifact's build dependencies to derive a deterministic tag. For each dependency file it opens/hashes the file; if hashing a file fails for a reason other than the file not existing (which is skipped), the error is wrapped as 'getting hash for %q:'.
Source
Thrown at pkg/skaffold/tag/input_digest.go:82
if image.KanikoArtifact != nil {
srcFiles = append(srcFiles, image.KanikoArtifact.DockerfilePath)
}
if image.CustomArtifact != nil && image.CustomArtifact.Dependencies != nil && image.CustomArtifact.Dependencies.Dockerfile != nil {
srcFiles = append(srcFiles, image.CustomArtifact.Dependencies.Dockerfile.Path)
}
// must sort as hashing is sensitive to the order in which files are processed
sort.Strings(srcFiles)
for _, d := range srcFiles {
h, err := fileHasher(d, image.Workspace)
if err != nil {
if os.IsNotExist(err) {
log.Entry(ctx).Tracef("skipping dependency %q for artifact cache calculation: %v", d, err)
continue // Ignore files that don't exist
}
return "", fmt.Errorf("getting hash for %q: %w", d, err)
}
inputs = append(inputs, h)
}
return encode(inputs)
}
func encode(inputs []string) (string, error) {
// get a key for the hashes
hasher := sha256.New()
enc := json.NewEncoder(hasher)
if err := enc.Encode(inputs); err != nil {
return "", err
}
return hex.EncodeToString(hasher.Sum(nil)), nil
}
// fileHasher hashes the contents and name of a fileView on GitHub (pinned to a1189de023)
Solutions
- Fix permissions on the dependency file (chmod/chown so the build user can read it)
- Remove or correct the offending dependency path in skaffold.yaml build.artifacts.dependencies
- Re-run after syncing the workspace — the file may have been deleted concurrently
- Point dependencies at regular files, not directories or broken symlinks
Example fix
// before dependencies: - paths: ["secrets.key"] # mode 0600, owned by root // after sudo chmod a+r secrets.key # or list a readable copy in dependencies
Defensive patterns
Strategy: validation
Validate before calling
for _, d := range artifact.Dependencies {
if _, err := os.Stat(d); os.IsPermission(err) || isDir(d) {
return fmt.Errorf("dependency %q unreadable or not a regular file", d)
}
} Try / catch
tag, err := tagger.GenerateTag(ctx, image)
var pathErr error
if errors.As(err, &pathErr) {
return fmt.Errorf("check permissions/existence of dependency files: %w", err)
} Prevention
- Verify dependency paths in skaffold.yaml are readable regular files
- Avoid listing directories or volatile temp files as dependencies
- Run builds with a user that owns/can-read the workspace
- Re-check dependencies after concurrent workspace mutations
When it happens
Trigger: GenerateTag on an artifact whose dependency paths include a file that exists in the dependency list but cannot be opened/hashed: permission-denied, a path that is a directory, a broken symlink, or an I/O error while reading.
Common situations: Dependencies declared in skaffold.yaml pointing to paths with wrong permissions in CI; a dependency listed as a directory or glob that resolves oddly; files deleted between listing and hashing in a concurrently modified workspace.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- finding current directory: %w
- bad timezone provided: %q, error: %s
- parsing template: %w
- environment variables missing for template keys
- %q is not a valid git tagger variant
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/f3d32280084345ea.
Report an issue: GitHub.