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
returnView on GitHub (pinned to a1189de023)
Solutions
- Ensure the config file exists — run any skaffold command once or call ResolveConfigFile first, which creates the file
- Fix file permissions (chmod/chown so the running user can read it)
- 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
- Create the config via ResolveConfigFile before reading directly
- Check file permissions after running with sudo
- Avoid deleting ~/.skaffold/config.yaml while skaffold runs
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
- retrieving home directory: %w
- normalizing dockerfile path: %w
- writing config to file: %w
- creating parent directory: %w
- creating file: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/a280c1a34465d285.
Report an issue: GitHub.