hashicorp/terraform · error
configuration file did not contain profile
Error message
configuration file did not contain profile: %s
What it means
Thrown by checkProfile() in the OCI backend when the specified profile name is not found in the OCI config file (typically ~/.oci/config). The function reads the file line-by-line and matches INI-style section headers ([profile_name]) via regex '^\\[(.*)\\]'. If no section header matches the requested profile, this error is returned.
Solutions
- List available profiles: cat ~/.oci/config and verify the section header matches your backend 'profile' value exactly.
- Run 'oci setup config' to create the profile if it doesn't exist.
- Ensure the 'config_file' backend attribute points to the correct file path containing the profile.
- Check for case mismatches — 'DEFAULT' and 'default' are treated as distinct profile names by this matching logic.
Example fix
// backend config — ensure profile matches a [section] in ~/.oci/config
terraform {
backend "oci" {
// before (typo)
profile = "producton"
// after
profile = "production"
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate OCI config profile existence before Terraform init
import (
"os"
"regexp"
"strings"
)
func validateOCIProfile(configPath, profile string) error {
data, err := os.ReadFile(configPath)
if err != nil {
return fmt.Errorf("cannot read OCI config at %s: %w", configPath, err)
}
profileRegex := regexp.MustCompile(`^\[(.*)\]`)
for _, line := range strings.Split(string(data), "\n") {
if match := profileRegex.FindStringSubmatch(line); match != nil && len(match) > 1 && match[1] == profile {
return nil
}
}
return fmt.Errorf("profile %q not found in %s — available profiles can be listed with: grep '^\[' %s", profile, configPath, configPath)
} Prevention
- Run 'oci setup config' and note the profile name you create.
- Use 'oci iam region list --profile <name>' to verify the profile works before configuring the Terraform backend.
- Keep the config_file and profile attributes in the backend block consistent with your ~/.oci/config.
When it happens
Trigger: checkProfile(profile, path) is called during OCI backend configuration. It reads the config file at the given path, splits by newline, and searches for a line matching '[profile]'. Fails when: the profile name has a typo, the config file uses a different format, or the profile section simply doesn't exist.
Common situations: Typo in the 'profile' attribute of the backend configuration block. Using 'DEFAULT' vs 'default' (case-sensitive match). Config file path points to wrong file. New machine without 'oci setup' having been run. Profile created in a different config file than the one pointed to by the 'config_file' attribute.
Related errors
- missing profile in provider block
- auth must be one of ' ' or ' ' or ' ' or ' ' or ' ' or
- can not get private_key or private_key_path from Terraform…
- can not get from Terraform configuration (SecurityToken)
- could not create security token based auth config provider
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e444e882bc329dc8.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/util.go:68
return ""
}
return home
}
func checkProfile(profile string, path string) (err error) {
var profileRegex = regexp.MustCompile(`^\[(.*)\]`)
data, err := os.ReadFile(path)
if err != nil {
return err
}
content := string(data)
splitContent := strings.Split(content, "\n")
for _, line := range splitContent {
if match := profileRegex.FindStringSubmatch(line); match != nil && len(match) > 1 && match[1] == profile {
return nil
}
}
return fmt.Errorf("configuration file did not contain profile: %s", profile)
}
// cleans and expands the path if it contains a tilde , returns the expanded path or the input path as is if not expansion
// was performed
func expandPath(filepath string) string {
if strings.HasPrefix(filepath, fmt.Sprintf("~%c", os.PathSeparator)) {
filepath = path.Join(getHomeFolder(), filepath[2:])
}
return path.Clean(filepath)
}
func getBackendAttrWithDefault(obj cty.Value, attrName, def string) (cty.Value, bool) {
value := backendbase.GetAttrDefault(obj, attrName, cty.StringVal(getEnvSettingWithDefault(attrName, def)))
return value, value.IsKnown() && !value.IsNull()
}
func getBackendAttr(obj cty.Value, attrName string) (cty.Value, bool) {
return getBackendAttrWithDefault(obj, attrName, "")View on GitHub (pinned to d32a084675)