hashicorp/terraform · error

can't locate credentials file

Error message

can't locate credentials file: %s

What it means

Thrown when CredentialsConfigFile() fails to determine the path to the credentials file, and this error propagates when building the credentials source in CredentialsSource(). CredentialsConfigFile() internally calls ConfigDir() which resolves the user's config/home directory; if that fails, the credentials file path cannot be constructed. The source comment notes this is very unlikely since a Config object was already loaded.

Solutions

  1. Set the HOME environment variable: export HOME=/home/user
  2. Use TF_CLI_CONFIG_FILE to specify an explicit config file path
  3. For containers, ensure the user has a home directory set: docker run -e HOME=/root ...
  4. Set up credentials via terraform login after fixing the HOME environment

Example fix

# before (container without HOME)
docker run hashicorp/terraform plan

# after
docker run -e HOME=/root hashicorp/terraform plan
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify HOME is resolvable before running terraform
func checkHomeEnv() error {
    home, err := os.UserHomeDir()
    if err != nil {
        return fmt.Errorf("cannot determine home directory: %w", err)
    }
    if home == "" {
        return errors.New("HOME is not set; cannot locate credentials file")
    }
    return nil
}

Prevention

When it happens

Trigger: CredentialsConfigFile() returns an error because ConfigDir() cannot resolve the user's home or config directory. This propagates from CredentialsSource() which needs the credentials file path to set up local credential storage.

Common situations: HOME or USERPROFILE environment variable not set (common in containers, systemd services, or CI runners without proper env); running Terraform as a service account without a home directory; exotic platform without standard home directory resolution.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/83f146b3a6f5692d. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/cliconfig/credentials.go:45

// that the credentials source will use when asked to save or forget credentials
// and when a "credentials helper" program is not active.
func CredentialsConfigFile() (string, error) {
	configDir, err := ConfigDir()
	if err != nil {
		return "", err
	}
	return filepath.Join(configDir, "credentials.tfrc.json"), nil
}

// CredentialsSource creates and returns a service credentials source whose
// behavior depends on which "credentials" and "credentials_helper" blocks,
// if any, are present in the receiving config.
func (c *Config) CredentialsSource(helperPlugins pluginDiscovery.PluginMetaSet) (*CredentialsSource, error) {
	credentialsFilePath, err := CredentialsConfigFile()
	if err != nil {
		// If we managed to load a Config object at all then we would already
		// have located this file, so this error is very unlikely.
		return nil, fmt.Errorf("can't locate credentials file: %s", err)
	}

	var helper svcauth.CredentialsSource
	var helperType string
	for givenType, givenConfig := range c.CredentialsHelpers {
		available := helperPlugins.WithName(givenType)
		if available.Count() == 0 {
			log.Printf("[ERROR] Unable to find credentials helper %q; ignoring", givenType)
			break
		}

		selected := available.Newest()

		helperSource := svcauth.HelperProgramCredentialsSource(selected.Path, givenConfig.Args...)
		helper = svcauth.CachingCredentialsSource(helperSource) // cached because external operation may be slow/expensive
		helperType = givenType

		// There should only be zero or one "credentials_helper" blocks. We

View on GitHub (pinned to d32a084675)