diff --git a/internal/bootstrap/config_yaml.go b/internal/bootstrap/config_yaml.go index e2f5ed6..26224ef 100644 --- a/internal/bootstrap/config_yaml.go +++ b/internal/bootstrap/config_yaml.go @@ -342,13 +342,15 @@ func loadConfigFromYAML(cfg *Config, filePath string) error { return nil } -// isConfigFileNotFound returns true if the error indicates the config file does not exist. -// Handles both viper's ConfigFileNotFoundError and OS-level file-not-found errors. +// isConfigFileNotFound returns true if the error indicates the config file cannot be read +// due to absence or restrictive permissions. In distroless containers, attempting to open +// a file under a root-owned directory may return EACCES instead of ENOENT. Both cases +// should fall back gracefully to env-only configuration. func isConfigFileNotFound(err error) bool { var notFoundErr viper.ConfigFileNotFoundError if errors.As(err, ¬FoundErr) { return true } - return os.IsNotExist(err) + return os.IsNotExist(err) || os.IsPermission(err) || errors.Is(err, os.ErrPermission) } diff --git a/internal/bootstrap/config_yaml_test.go b/internal/bootstrap/config_yaml_test.go index 083e3f4..e8b4e2b 100644 --- a/internal/bootstrap/config_yaml_test.go +++ b/internal/bootstrap/config_yaml_test.go @@ -7,6 +7,7 @@ package bootstrap import ( + "fmt" "os" "path/filepath" "strings" @@ -499,6 +500,16 @@ func TestIsConfigFileNotFound(t *testing.T) { err: viper.ConfigFileNotFoundError{}, expected: true, }, + { + name: "permission denied error", + err: os.ErrPermission, + expected: true, + }, + { + name: "wrapped permission denied error", + err: fmt.Errorf("read config: %w", os.ErrPermission), + expected: true, + }, { name: "generic error", err: assert.AnError,