GoogleContainerTools/skaffold · error

%s %q: %w

Error message

%s %q: %w

What it means

Push fails with "<PushImageErr> %q" (sErrors.PushImageErr, typically "pushing image") when remote.Write cannot upload the loaded tarball image to the target registry. This wraps go-containerregistry's remote.Write error — auth failures, TLS problems, connectivity, blob upload errors, or registry denial (quota, permissions).

Source

Thrown at pkg/skaffold/docker/remote.go:114

	}

	return img.ConfigFile()
}

// Push pushes the tarball image
func Push(tarPath, tag string, cfg Config, platforms []specs.Platform) (string, error) {
	t, err := name.NewTag(tag, name.WeakValidation)
	if err != nil {
		return "", fmt.Errorf("parsing tag %q: %w", tag, err)
	}

	i, err := tarball.ImageFromPath(tarPath, nil)
	if err != nil {
		return "", fmt.Errorf("reading image %q: %w", tarPath, err)
	}

	if err := remote.Write(t, i, remote.WithAuthFromKeychain(primaryKeychain)); err != nil {
		return "", fmt.Errorf("%s %q: %w", sErrors.PushImageErr, t, err)
	}

	return getRemoteDigest(tag, cfg, platforms)
}

func getRemoteImage(identifier string, cfg Config, platform v1.Platform) (v1.Image, error) {
	ref, err := parseReference(identifier, cfg)
	if err != nil {
		return nil, err
	}
	options := []remote.Option{
		remote.WithAuthFromKeychain(primaryKeychain),
	}
	if IsInsecure(ref, cfg.GetInsecureRegistries()) {
		options = append(options, insecureTransportOption())
	}
	if platform.String() != "" {
		options = append(options, remote.WithPlatform(platform))

View on GitHub (pinned to a1189de023)

Solutions

  1. Authenticate: `docker login <registry>` (or configure the proper credential helper for gcloud/aws/ecr) and retry.
  2. Read the wrapped error — a 401/403 indicates credentials/permissions; DENIED indicates repo policy; timeout indicates network/proxy.
  3. Verify push permission on the target repository/project (IAM, or repo-level ACLs in Harbor/Quay).
  4. If the registry is HTTP or has a self-signed cert, add it to insecure_registries in the Skaffold config.
  5. Check registry-side limits (quota, rate limits, image size) and egress/proxy settings.

Example fix

// before
docker.Push(tarPath, "us.gcr.io/proj/app:v1", cfg, nil) // 403 DENIED
// after
# grant push access / login first
# gcloud auth activate-service-account --key-file=sa.json
# gcloud auth configure-docker us.gcr.io
docker.Push(tarPath, "us.gcr.io/proj/app:v1", cfg, nil)
Defensive patterns

Strategy: try-catch

Validate before calling

func canPush(ref string) error {
	repo, err := name.NewRepository(ref, name.WeakValidation)
	if err != nil { return err }
	_, err = remote.Index(repo, remote.WithAuthFromKeychain(defaultKeychain())) // auth smoke test
	if err != nil {
		var te *transport.Error
		if errors.As(err, &te) && (te.StatusCode == 401 || te.StatusCode == 403) {
			return fmt.Errorf("no push credentials/permissions for %s", ref)
		}
	}
	return nil
}

Type guard

func hasRegistryAuth(registry string) bool {
	cfg, err := config.Load()
	if err != nil { return false }
	auth, err := cfg.GetAuth(registry)
	return err == nil && auth != authn.Anonymous
}

Try / catch

if _, err := docker.Push(tarPath, tag, cfg, platforms); err != nil {
	var te *transport.Error
	if errors.As(err, &te) {
		switch te.StatusCode {
		case 401, 403: return fmt.Errorf("run `docker login %s` and verify push permissions", registryOf(tag))
		case http.StatusGatewayTimeout: return fmt.Errorf("registry timeout; check network/proxy")
		}
	}
	return err
}

Prevention

When it happens

Trigger: remote.Write to the parsed tag fails: unauthenticated/unauthorized (401/403), registry unreachable, insecure registry without skip-verify configured, image exceeds repo size limits, or tag already protected.

Common situations: docker login never run for the registry or token expired; GCR/Artifact Registry permissions missing on the service account; corporate proxy blocking the upload; pushing to a read-only mirror.

Related errors


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