docker/cli · error

loading config file

Error message

loading config file: %w

What it means

Returned by the internal `load` function (config.go:137-145) when os.Open of the config file (config.json) fails with any error OTHER than "not exists". The not-exists case is tolerated (default struct returned), but permission errors, I/O errors, or broken symlinks are wrapped with this message.

Solutions

  1. Check permissions on the file reported: `ls -la ~/.docker/config.json` and the parent directory; ensure the current user can read both.
  2. Verify DOCKER_CONFIG points to a readable, existing directory (`echo $DOCKER_CONFIG`).
  3. If the file is corrupt or locked by another process, fix the lock or restore a valid config.
  4. As a last resort, move the unreadable file aside and let Docker recreate a default config.

Example fix

# before — file not readable
$ ls -la ~/.docker/config.json
-rw------- 1 root root ... config.json
# after — fix ownership/permissions
$ sudo chown $USER:$USER ~/.docker/config.json
$ chmod 600 ~/.docker/config.json
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check readability before relying on config.Load.
if _, err := os.Stat(filename); err != nil {
    return fmt.Errorf("config file inaccessible: %w", err)
}
// ensure readable bit for current user
if fi, _ := os.Stat(filename); fi != nil && fi.Mode().Perm()&0o400 == 0 {
    return errors.New("config file not readable")
}

Try / catch

cfg, err := config.Load(dir)
if err != nil {
    return fmt.Errorf("cannot load docker config from %s: %w", dir, err)
}

Prevention

When it happens

Trigger: config.Load(configDir) -> load() -> os.Open(filename) returns a non-IsNotExist error. Typical causes: the file exists but lacks read permission, the parent directory is unreadable, or a symlink target is broken in a way that yields EIO/EACCES rather than ENOENT.

Common situations: The `~/.docker/config.json` file (or DOCKER_CONFIG location) exists but is owned by another user / has mode 000, was created on a different user account, or sits on a filesystem that fails to open. Also occurs when DOCKER_CONFIG points to a directory the process cannot traverse.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/cc8dd768c6b6ca31. Report an issue: GitHub.

Appendix: source

Thrown at cli/config/config.go:145

	if configDir == "" {
		configDir = Dir()
	}
	return load(configDir)
}

func load(configDir string) (*configfile.ConfigFile, error) {
	filename := filepath.Join(configDir, ConfigFileName)
	configFile := configfile.New(filename)

	file, err := os.Open(filename)
	if err != nil {
		if os.IsNotExist(err) {
			// It is OK for no configuration file to be present, in which
			// case we return a default struct.
			return configFile, nil
		}
		// Any other error happening when failing to read the file must be returned.
		return configFile, fmt.Errorf("loading config file: %w", err)
	}
	defer func() { _ = file.Close() }()
	err = configFile.LoadFromReader(file)
	if err != nil {
		err = fmt.Errorf("parsing config file (%s): %w", filename, err)
	}
	return configFile, err
}

// LoadDefaultConfigFile attempts to load the default config file and returns
// a reference to the ConfigFile struct. If none is found or when failing to load
// the configuration file, it initializes a default ConfigFile struct. If no
// credentials-store is set in the configuration file, it attempts to discover
// the default store to use for the current platform.
//
// Important: LoadDefaultConfigFile prints a warning to stderr when failing to
// load the configuration file, but otherwise ignores errors. Consumers should
// consider using [Load] (and [credentials.DetectDefaultStore]) to detect errors

View on GitHub (pinned to 4f84911bfe)