docker/cli · error

saving creds

Error message

saving creds: %w

What it means

Thrown inside copyDockerConfigIntoContainer (create.go:406) when configfile.ConfigFile.SaveToWriter fails while serializing the local Docker config (credentials, auths) into an in-memory buffer. This is the step that prepares the config.json to be copied into the newly created container. The wrapped error (%w) carries the underlying serialization failure.

Solutions

  1. Inspect ~/.docker/config.json for syntax errors: docker login again to regenerate it.
  2. Remove or fix malformed auths/credsStore/credHelpers entries and re-login.
  3. Back up and regenerate the config: mv ~/.docker/config.json config.json.bak && docker login.
  4. If a credential helper is involved, verify it is installed and produces valid output.

Example fix

# before (corrupt config)
cat ~/.docker/config.json  # has a malformed "auths" entry

# after
mv ~/.docker/config.json ~/.docker/config.json.bak
docker login
Defensive patterns

Strategy: try-catch

Validate before calling

// Before create, sanity-check the config parses round-trips:
import "github.com/docker/cli/cli/config/configfile"
f, err := config.Load(os.Getenv("DOCKER_CONFIG"))
if err != nil { return err }
var buf bytes.Buffer
if err := f.SaveToWriter(&buf); err != nil {
    return fmt.Errorf("docker config cannot be serialized: %w", err)
}

Try / catch

// Because this is a wrapped error returned from docker create, treat it as
// a config-integrity problem, not a transient one:
if err := createCmd.Run(); err != nil && strings.Contains(err.Error(), "saving creds") {
    // regenerate ~/.docker/config.json
}

Prevention

When it happens

Trigger: `docker create`/`docker run` runs in a context where the user's ~/.docker/config.json exists but is structurally invalid — e.g. a corrupt credsStore field, an auth entry that cannot be re-encoded, or an incompatible credential helper entry that SaveToWriter cannot marshal.

Common situations: Migrating from an older Docker version that wrote a config field no longer understood, a manually edited config.json, a credsStore/credHelpers entry pointing at a helper binary that returns malformed data, or a config produced by another tool.

Related errors


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

Appendix: source

Thrown at cli/command/container/create.go:406

		return fmt.Errorf(
			"invalid pull option: '%s': must be one of %q, %q or %q",
			val,
			PullImageAlways,
			PullImageMissing,
			PullImageNever,
		)
	}
}

// copyDockerConfigIntoContainer takes the client configuration and copies it
// into the container.
//
// The path should be an absolute path in the container, commonly
// /root/.docker/config.json.
func copyDockerConfigIntoContainer(ctx context.Context, apiClient client.APIClient, containerID string, configPath string, config *configfile.ConfigFile) error {
	var configBuf bytes.Buffer
	if err := config.SaveToWriter(&configBuf); err != nil {
		return fmt.Errorf("saving creds: %w", err)
	}

	// We don't need to get super fancy with the tar creation.
	var tarBuf bytes.Buffer
	tarWriter := tar.NewWriter(&tarBuf)
	_ = tarWriter.WriteHeader(&tar.Header{
		Name: configPath,
		Size: int64(configBuf.Len()),
		Mode: 0o600,
	})

	if _, err := io.Copy(tarWriter, &configBuf); err != nil {
		_ = tarWriter.Close()
		return fmt.Errorf("writing config to tar file for config copy: %w", err)
	}

	if err := tarWriter.Close(); err != nil {
		return fmt.Errorf("closing tar for config copy failed: %w", err)

View on GitHub (pinned to 4f84911bfe)