GoogleContainerTools/skaffold · error

normalizing dockerfile path: %w

Error message

normalizing dockerfile path: %w

What it means

SyncMap fails with "normalizing dockerfile path" when NormalizeDockerfilePath cannot resolve the Dockerfile path relative to the workspace — typically the file does not exist at workspace/dockerfilePath and isn't reachable via a remote URL. Skaffold requires an absolute, readable Dockerfile before parsing COPY/ADD commands for file sync.

Source

Thrown at pkg/skaffold/docker/syncmap.go:36

import (
	"context"
	"fmt"
	"os"
	"path"
	"path/filepath"

	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util"
	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/walk"
)

// SyncMap creates a map of syncable files by looking at the COPY/ADD commands in the Dockerfile.
// All keys are relative to the Skaffold root, the destinations are absolute container paths.
// TODO(corneliusweig) destinations are not resolved across stages in multistage dockerfiles. Is there a use-case for that?
func SyncMap(ctx context.Context, workspace string, dockerfilePath string, buildArgs map[string]*string, cfg Config) (map[string][]string, error) {
	absDockerfilePath, err := NormalizeDockerfilePath(workspace, dockerfilePath)
	if err != nil {
		return nil, fmt.Errorf("normalizing dockerfile path: %w", err)
	}

	// only the COPY/ADD commands from the last image are syncable
	fts, err := ReadCopyCmdsFromDockerfile(ctx, true, absDockerfilePath, workspace, buildArgs, cfg)
	if err != nil {
		return nil, err
	}

	excludes, err := readDockerignore(workspace, absDockerfilePath)
	if err != nil {
		return nil, fmt.Errorf("reading .dockerignore: %w", err)
	}

	srcByDest, err := walkWorkspaceWithDestinations(workspace, excludes, fts)
	if err != nil {
		return nil, fmt.Errorf("walking workspace: %w", err)
	}

View on GitHub (pinned to a1189de023)

Solutions

  1. Check the resolved path exists: combine workspace + dockerfilePath and verify with ls; fix the path in skaffold.yaml (dockerfile: field).
  2. Make the dockerfile path absolute or correct relative to the artifact's workspace/context.
  3. Ensure the Dockerfile is generated before SyncMap runs if it is produced by a build step.
  4. Verify correct working directory when invoking Skaffold with relative paths.
  5. Check file permissions — the file must be readable.

Example fix

// before
# skaffold.yaml
build.artifacts[].docker.dockerfile: ./Dockerfile.prod  # file is actually at deploy/Dockerfile.prod
// after
build.artifacts[].docker.dockerfile: ./deploy/Dockerfile.prod
Defensive patterns

Strategy: validation

Validate before calling

func dockerfileExists(workspace, dockerfilePath string) error {
	if strings.HasPrefix(dockerfilePath, "http://") || strings.HasPrefix(dockerfilePath, "https://") {
		return nil // remote dockerfiles are fetched by skaffold
	}
	p := dockerfilePath
	if !filepath.IsAbs(p) { p = filepath.Join(workspace, p) }
	fi, err := os.Stat(p)
	if err != nil { return fmt.Errorf("dockerfile not found at %s", p) }
	if fi.IsDir() { return fmt.Errorf("%s is a directory", p) }
	return nil
}

Type guard

func hasReadableDockerfile(workspace, p string) bool {
	return dockerfileExists(workspace, p) == nil
}

Try / catch

if err := dockerfileExists(workspace, dockerfilePath); err != nil { return err }
if _, err := docker.SyncMap(ctx, workspace, dockerfilePath, buildArgs, cfg); err != nil {
	if strings.Contains(err.Error(), "normalizing dockerfile path") {
		return fmt.Errorf("fix `dockerfile:` path in skaffold.yaml — %v", err)
	}
	return err
}

Prevention

When it happens

Trigger: SyncMap called with a dockerfilePath that doesn't exist under workspace; path uses wrong separators or ../ escapes outside the workspace; dockerfile configured but never committed/generated; typo in the skaffold.yaml dockerfile field.

Common situations: dockerfile path points at a Dockerfile in a different directory than the artifact context; file renamed (Dockerfile.dev vs Dockerfile); running Skaffold from a different cwd with a relative path; multi-module repo where the path is relative to repo root not workspace.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/ace0241bfc140ee1. Report an issue: GitHub.