GoogleContainerTools/skaffold · error

reading global config: %w

Error message

reading global config: %w

What it means

ReadConfigFileNoCache reads the global config YAML from disk and wraps os.ReadFile failures with this error. Note it first logs a warning and only then returns the wrapped error — the typical cause is the config file not existing or being unreadable.

Source

Thrown at pkg/skaffold/config/util.go:111

// ResolveConfigFile determines the default config location, if the configFile argument is empty.
func ResolveConfigFile(configFile string) (string, error) {
	if configFile == "" {
		home, err := homedir.Dir()
		if err != nil {
			return "", fmt.Errorf("retrieving home directory: %w", err)
		}
		configFile = filepath.Join(home, defaultConfigDir, defaultConfigFile)
	}
	return configFile, util.VerifyOrCreateFile(configFile)
}

// ReadConfigFileNoCache reads the given config yaml file and unmarshals the contents.
// Only visible for testing, use ReadConfigFile instead.
func ReadConfigFileNoCache(configFile string) (*GlobalConfig, error) {
	contents, err := os.ReadFile(configFile)
	if err != nil {
		log.Entry(context.TODO()).Warnf("Could not load global Skaffold defaults. Error encounter while reading file %q", configFile)
		return nil, fmt.Errorf("reading global config: %w", err)
	}
	config := GlobalConfig{}
	if err := yaml.Unmarshal(contents, &config); err != nil {
		log.Entry(context.TODO()).Warnf("Could not load global Skaffold defaults. Error encounter while unmarshalling the contents of file %q", configFile)
		return nil, fmt.Errorf("unmarshalling global skaffold config: %w", err)
	}
	return &config, nil
}

// GetConfigForCurrentKubectx returns the specific config to be modified based on the kubeContext.
// Either returns the config corresponding to the provided or current context,
// or the global config.
func getConfigForCurrentKubectx(configFile string) (*ContextConfig, error) {
	configOnce.Do(func() {
		cfg, err := ReadConfigFile(configFile)
		if err != nil {
			configErr = err
			return

View on GitHub (pinned to a1189de023)

Solutions

  1. Ensure the config file exists — run any skaffold command once or call ResolveConfigFile first, which creates the file
  2. Fix file permissions (chmod/chown so the running user can read it)
  3. Verify the configFile path passed is correct and not a directory

Example fix

// before
cfg, err := ReadConfigFileNoCache("~/.skaffold/config.yaml") // may not exist
// after
configFile, err := ResolveConfigFile("")
if err != nil { return err }
cfg, err := ReadConfigFileNoCache(configFile)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(configFile); err != nil {
  if os.IsNotExist(err) { configFile, err = config.ResolveConfigFile("") } // creates it
} else if info, _ := os.Stat(configFile); info.IsDir() {
  return errors.New("config path is a directory")
}

Try / catch

cfg, err := config.ReadConfigFileNoCache(configFile)
if err != nil && strings.Contains(err.Error(), "reading global config") {
  log.Warn("global config unreadable; using empty defaults")
  cfg = &config.GlobalConfig{}
}

Prevention

When it happens

Trigger: Calling ReadConfigFileNoCache with a path that does not exist, has wrong permissions, or is a directory — i.e. os.ReadFile returns any error.

Common situations: First run before ~/.skaffold/config.yaml was ever created (usually resolved by VerifyOrCreateFile upstream, but direct calls skip that); file deleted while skaffold runs; permission denied after sudo/chown changes.

Related errors


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