hashicorp/terraform · error

reading OIDC Token from file %q: %v

Error message

reading OIDC Token from file %q: %v

What it means

Raised by the Azure remote-state backend's getOidcToken helper (helpers.go:51) when the backend option `oidc_token_file_path` is set but os.ReadFile fails to read that file. The file is expected to contain a JWT OIDC token used for federated/workload-identity auth against Azure Storage; the underlying OS error (no such file, permission denied, is a directory) is wrapped into the message.

Source

Thrown at internal/backend/remote-state/azure/helpers.go:51

	if clientCertificate != "" {
		out := make([]byte, base64.StdEncoding.DecodedLen(len(clientCertificate)))
		n, err := base64.StdEncoding.Decode(out, []byte(clientCertificate))
		if err != nil {
			return pfx, fmt.Errorf("could not decode client certificate data: %v", err)
		}
		pfx = out[:n]
	}
	return pfx, nil
}

func getOidcToken(d *backendbase.SDKLikeData) (*string, error) {
	idToken := strings.TrimSpace(d.String("oidc_token"))

	if path := d.String("oidc_token_file_path"); path != "" {
		fileTokenRaw, err := os.ReadFile(path)

		if err != nil {
			return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err)
		}

		fileToken := strings.TrimSpace(string(fileTokenRaw))

		if idToken != "" && idToken != fileToken {
			return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match")
		}

		idToken = fileToken
	}

	if d.Bool("use_aks_workload_identity") && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" {
		path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE")
		fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE"))

		if err != nil {
			return nil, fmt.Errorf("reading OIDC Token from file %q provided by AKS Workload Identity: %v", path, err)
		}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify the path exists and is readable: `test -r "$path" && echo ok`.
  2. Run terraform as a user/uid that has read permission on the token file.
  3. If sourcing the token dynamically, unset oidc_token_file_path and use a credential process / env var instead.
  4. Fix typos, trailing whitespace, or an incorrect volume-mount path in the configured value.

Example fix

# before
terraform {
  backend "azurerm" {
    oidc_token_file_path = "/var/run/secrets/tokn"  # typo
  }
}
# after
terraform {
  backend "azurerm" {
    oidc_token_file_path = "/var/run/secrets/token"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# preflight before `terraform init`
f="${TF_VAR_oidc_token_file_path:-/var/run/secrets/oidc/token}"
if [ -n "$TF_VAR_oidc_token_file_path" ] || [ -n "$oidc_token_file_path" ]; then
  test -r "$f" || { echo "oidc token file not readable: $f" >&2; exit 1; }
fi

Prevention

When it happens

Trigger: Configuring `terraform { backend "azurerm" {} }` (or the azurerm auth block of the remote backend) with `oidc_token_file_path` pointing at a path that does not exist, is not readable by the terraform process, or names a directory, then running terraform init.

Common situations: CI/locally using a stale file path from another pipeline; the file path set via an env var that was never populated in the current shell; a Kubernetes mounted-secret path that differs from the config; typos or trailing whitespace in the path.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/f2f5ccb59d4db05e. Report an issue: GitHub.