hasura/graphql-engine · error · errors.Error
cannot read global config from file/env: %w
Error message
cannot read global config from file/env: %w
What it means
readGlobalConfig uses viper to read config.yaml in ec.GlobalConfigDir plus environment overrides, and v.ReadInConfig() failed. Unlike 215, this covers viper-level failures: unreadable file (permissions on an existing config), unsupported/ambiguous config format for the discovered file, or env-var binding issues; a genuinely absent file is normally handled as NotFound elsewhere.
Source
Thrown at cli/global_config.go:227
return nil
}
// readGlobalConfig reads the configuration from global config file env vars,
// through viper.
func (ec *ExecutionContext) readGlobalConfig() error {
var op errors.Op = "cli.ExecutionContext.readGlobalConfig"
// need to get existing viper because https://github.com/spf13/viper/issues/233
v := viper.New()
v.SetEnvPrefix("HASURA_GRAPHQL")
v.AutomaticEnv()
v.SetConfigName("config")
v.AddConfigPath(ec.GlobalConfigDir)
v.SetDefault("cli_environment", DefaultEnvironment)
err := v.ReadInConfig()
if err != nil {
return errors.E(op, fmt.Errorf("cannot read global config from file/env: %w", err))
}
if ec.GlobalConfig == nil {
ec.Logger.Debugf("global config is not pre-set, reading from current env")
ec.GlobalConfig = &GlobalConfig{
UUID: v.GetString("uuid"),
EnableTelemetry: v.GetBool("enable_telemetry"),
ShowUpdateNotification: v.GetBool("show_update_notification"),
CLIEnvironment: Environment(v.GetString("cli_environment")),
}
} else {
ec.Logger.Debugf("global config is pre-set to %#v", ec.GlobalConfig)
}
ec.Logger.Debugf("global config: uuid: %v", ec.GlobalConfig.UUID)
ec.Logger.Debugf("global config: enableTelemetry: %v", ec.GlobalConfig.EnableTelemetry)
ec.Logger.Debugf(
"global config: showUpdateNotification: %v",View on GitHub (pinned to 724551b9ae)
Solutions
- Inspect the wrapped viper error: ConfigFileNotFoundError means path issues, *fs.PathError means permissions, IncompatibleConfigError means wrong types
- Fix permissions/ownership of GlobalConfigDir/config.* so the running user can read it
- Rename the config file to config.yaml (the name SetConfigName("config") expects) and ensure a supported extension
- Sanitize environment variables that override config values to valid types
Example fix
# before -rw------- 1 root root /root/.mycli/config.yaml # after $ sudo chmod 644 /root/.mycli/config.yaml
Defensive patterns
Strategy: validation
Validate before calling
p := filepath.Join(ec.GlobalConfigDir, "config.yaml")
if _, err := os.Stat(p); err == nil {
if f, err := os.Open(p); err != nil {
return fmt.Errorf("config exists but is unreadable: %w", err)
}
_ = f.Close()
} Type guard
func configReadableAndNamed(dir string) bool {
p := filepath.Join(dir, "config.yaml")
f, err := os.Open(p)
if err != nil {
return false
}
_ = f.Close()
return true
} Try / catch
if err := ec.Prepare(ctx); err != nil {
if strings.Contains(err.Error(), "cannot read global config from file/env") {
var pathErr *fs.PathError
if stderrors.As(err, &pathErr) {
_ = os.Chmod(ec.GlobalConfigDir+"/config.yaml", 0o644)
return ec.Prepare(ctx)
}
}
return err
} Prevention
- Name the file exactly config.yaml with a supported extension
- Ensure read permissions for the invoking user on dir and file
- Keep env overrides type-compatible with config fields
When it happens
Trigger: GlobalConfigDir contains a config file that exists but cannot be opened (mode 000, ownership mismatch), has an extension viper cannot infer a format from, or global config was pre-set to nil while env vars referenced by SetDefault/bind fail to coerce.
Common situations: Root-created config files read by unprivileged users, a config file with an odd extension, stale viper cache of a deleted file, or env vars (CLI_ENVIRONMENT etc.) set to values that fail type coercion into config fields.
Related errors
- write file: %w
- cannot get home directory: %w
- cannot create global config directory: %w
- write global config file: %w
- writing global config file failed: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/8fad8d281440c0ae.
Report an issue: GitHub.