Skip to content

fix: avoid hard fail when no config json file is present#164

Merged
mdelapenya merged 10 commits into
docker:mainfrom
KatIsCoding:fix/avoid-hard-fail-no-config-json
Jun 23, 2026
Merged

fix: avoid hard fail when no config json file is present#164
mdelapenya merged 10 commits into
docker:mainfrom
KatIsCoding:fix/avoid-hard-fail-no-config-json

Conversation

@KatIsCoding

Copy link
Copy Markdown
Contributor

Closes: #149

Problem

Callers of config.Load(), config.AuthConfigs, config.AuthConfigForHostname, and the context package helpers (Current, New, Delete, store.inspect) hard-fail when ~/.docker/config.json does not exist, even though the absence of a config file is a perfectly valid state on a fresh Docker installation.

Root Cause

config.Filepath() returns a generic fmt.Errorf("config file does not exist (%s)", configFilePath) when the file is missing. Load() wraps that into "config path: ..." and propagates it upward. Because every caller treats any non-nil error as fatal, a missing config file tears down operations that should legitimately proceed with empty/default auth or the default context.

Fix

Introduce a sentinel error, config.ErrConfigFileNotFound, joined into the error returned by Filepath() via errors.Join, so callers can distinguish "no config file" from real I/O or parse failures using errors.Is.

  • config/auth.go: AuthConfigs and AuthConfigForHostname return an empty auth config when the file is missing, instead of erroring.
  • context/current.go: Current() falls back to DefaultContextName (mirroring the existing os.IsNotExist branch for the meta file).
  • context/context.add.go, context/context.delete.go, context/store.go: the "set current" / "reset current" / inspect paths treat a missing config file as a no-op rather than failing.
  • config/load.go: Load() also tolerates os.ErrNotExist from loadFromFilepath (race between Filepath() and the read) by returning an empty Config.

Testing

  • No new tests added in this change. Existing config and context suites continue to pass.

@KatIsCoding KatIsCoding changed the title Fix/avoid hard fail no config json fix: avoid hard fail when no config json file is present Jun 21, 2026
@mdelapenya mdelapenya requested a review from Copilot June 22, 2026 05:59

@mdelapenya mdelapenya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, although I added a suggestion about the location of the new sentinel error. Also, could you unit test the new code paths?

Thanks for working on the fix!

Comment thread config/load.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to make the SDK tolerant of missing Docker CLI config (~/.docker/config.json) by introducing a sentinel error and updating config/auth/context helpers to treat “no config file” as a valid empty/default state instead of a fatal error.

Changes:

  • Add config.ErrConfigFileNotFound and include it in Filepath() errors to enable errors.Is-based handling.
  • Update auth helpers (AuthConfigs, AuthConfigForHostname) and context helpers (Current, New, Delete, store.inspect) to special-case the sentinel and avoid hard failures.
  • Make Load() tolerate os.ErrNotExist from the read path (race between existence check and open).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
config/load.go Introduces ErrConfigFileNotFound, joins it into Filepath() errors, and relaxes Load() for os.ErrNotExist.
config/auth.go Special-cases missing config file in auth entrypoints.
context/current.go Falls back to DefaultContextName when Docker config is missing.
context/context.add.go Treats missing config as a no-op when attempting to set the newly created context as current.
context/context.delete.go Treats missing config as a no-op when attempting to reset current context on delete.
context/store.go Treats missing config as a no-op during inspect (but currently skips required context field initialization).
Comments suppressed due to low confidence (1)

config/load.go:84

  • Even with ErrConfigFileNotFound, a very common "fresh install" state is that the directory (~/.docker / DOCKER_CONFIG) is missing. Dir() currently errors when the directory is absent, and that error does not include ErrConfigFileNotFound, so callers checking errors.Is(err, ErrConfigFileNotFound) will still hard-fail. To fully address the reported scenario, the missing-directory case needs to surface the same sentinel (or otherwise become distinguishable from real I/O/permission errors).
func Filepath() (string, error) {
	dir, err := Dir()
	if err != nil {
		return "", fmt.Errorf("config dir: %w", err)
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread context/store.go
Comment thread config/auth.go
Comment thread config/auth.go
Comment thread config/load.go
Comment thread context/context.add.go
Comment thread config/load.go
@KatIsCoding

Copy link
Copy Markdown
Contributor Author

@mdelapenya Thanks for your review! I implemented your suggestion, as well as some of the suggestions that copilot gave and the unit tests for the no config scenario!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread config/load.go
Comment thread config/load.go
@KatIsCoding

Copy link
Copy Markdown
Contributor Author

@mdelapenya I updated some of the code paths and now I think they make more sense, I believe that on a fresh docker install, the default ~/.docker/config.json path shouldn't fail even if it doesn't exist yet because that's a valid scenario, but if the config path has been overwritten to a non existing path then that's user error, and it may be worth it to report back that the path introduced doesn't exist, so now the sentinel error is only being used when the config path has not been updated by the user, and if it has been updated by the user then it may error correctly that the used path doesn't exist.

Let me know what you think!

@mdelapenya mdelapenya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@mdelapenya mdelapenya merged commit 59b3c5d into docker:main Jun 23, 2026
19 checks passed
@mdelapenya mdelapenya added the bug Something isn't working label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

config: hard failure when Docker config.json is missing

3 participants