hashicorp/terraform · error

unable to determine credentials file path

Error message

unable to determine credentials file path: %s

What it means

Thrown when s.CredentialsFilePath() returns an error during updateLocalHostCredentials, which writes credential updates to the local credentials file. Note: CredentialsFilePath() as implemented always returns (s.credentialsFilePath, nil) — it never produces an error — making this branch effectively unreachable defensive dead code. If it were ever triggered, it would mean the CredentialsSource was constructed without a valid credentials file path.

Solutions

  1. Report a bug to the Terraform project — this error path is not expected to be reachable
  2. Verify the CredentialsSource was initialized through normal config loading, not constructed manually
  3. Ensure HOME is set so the credentials file path can be resolved during initialization
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the credentials file path can be resolved before operations
// Note: CredentialsFilePath() currently always returns nil error, but guard anyway
func checkCredentialsPath(source *CredentialsSource) error {
    path, err := source.CredentialsFilePath()
    if err != nil {
        return fmt.Errorf("credentials file path error: %w", err)
    }
    if path == "" {
        return errors.New("credentials file path is empty")
    }
    return nil
}

Try / catch

// Guard credential updates; this error path is currently unreachable
// but defensive handling protects against future code changes
func safeUpdateCredentials(source *CredentialsSource, host svchost.Hostname, creds svcauth.HostCredentialsWritable) error {
    if _, err := source.CredentialsFilePath(); err != nil {
        return fmt.Errorf("cannot determine credentials path, skipping update: %w", err)
    }
    return nil
}

Prevention

When it happens

Trigger: s.CredentialsFilePath() returns a non-nil error when called from updateLocalHostCredentials. In the current implementation this cannot happen because CredentialsFilePath() unconditionally returns nil. It would require a future code change that makes path resolution fallible.

Common situations: Effectively unreachable in current Terraform. The defensive check exists to guard against a hypothetical future where CredentialsFilePath() becomes fallible. If encountered, it indicates an internal state corruption or a code regression.

Related errors


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

Appendix: source

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

		// Delegate entirely to the helper, then.
		if new == nil {
			return s.helper.ForgetForHost(host)
		}
		return s.helper.StoreForHost(host, new)
	default:
		// Should never happen because the above cases are exhaustive
		return fmt.Errorf("invalid credentials location %#v", loc)
	}
}

func (s *CredentialsSource) updateLocalHostCredentials(host svchost.Hostname, new svcauth.HostCredentialsWritable) error {
	// This function updates the local credentials file in particular,
	// regardless of whether a credentials helper is active. It should be
	// called only indirectly via updateHostCredentials.

	filename, err := s.CredentialsFilePath()
	if err != nil {
		return fmt.Errorf("unable to determine credentials file path: %s", err)
	}

	oldSrc, err := ioutil.ReadFile(filename)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("cannot read %s: %s", filename, err)
	}

	var raw map[string]interface{}

	if len(oldSrc) > 0 {
		// When decoding we use a custom decoder so we can decode any numbers as
		// json.Number and thus avoid losing any accuracy in our round-trip.
		dec := json.NewDecoder(bytes.NewReader(oldSrc))
		dec.UseNumber()
		err = dec.Decode(&raw)
		if err != nil {
			return fmt.Errorf("cannot read %s: %s", filename, err)
		}

View on GitHub (pinned to d32a084675)