TerraformPilot

DevOps

Fix Terraform Error: Invalid Escape Sequence in String

Fix terraform invalid escape sequence errors. Double backslashes for Windows paths, use heredocs for regex, and learn all valid HCL escape sequences.

LLuca Berton1 min read

Quick Answer

#
# ❌ Single backslash — invalid
path = "C:\Users\admin\scripts"
 
# ✅ Double backslash
path = "C:\\Users\\admin\\scripts"
 
# ✅ Or use forward slashes (works on Windows too)
path = "C:/Users/admin/scripts"

The Error

#
Error: Invalid escape sequence
 
  on main.tf line 5, in locals:
   5:   path = "C:\Users\admin"
 
The symbol "U" is not a valid escape sequence selector.

What Causes This

#

HCL (Terraform's language) only recognizes these escape sequences:

EscapeMeaning
\\Literal backslash
\"Literal quote
\nNewline
\rCarriage return
\tTab
\uNNNNUnicode character
\UNNNNNNNNUnicode character (8 hex digits)

Any other \ followed by a character is an error. \U in \Users isn't valid.

Solution 1: Double Backslashes

#
locals {
  # Windows paths
  script_path  = "C:\\Users\\admin\\scripts\\deploy.ps1"
  share_path   = "\\\\server\\share\\folder"
}

Solution 2: Forward Slashes

#

Most Windows tools accept forward slashes:

locals {
  script_path = "C:/Users/admin/scripts/deploy.ps1"
}
 
provisioner "local-exec" {
  command = "powershell -File C:/Users/admin/scripts/deploy.ps1"
}

Solution 3: Heredoc for Complex Strings

#
locals {
  # Heredoc — no escape processing
  script = <<-EOT
    $path = "C:\Users\admin\scripts"
    Get-ChildItem $path | ForEach-Object { $_.Name }
  EOT
}

Note: Heredocs still process ${...} interpolation. Use <<-'EOT' for completely raw strings (Terraform 1.7+):

locals {
  raw_script = <<-'EOT'
    No interpolation: ${this.is.literal}
    Backslashes work: C:\Users\admin
  EOT
}

Solution 4: Regex Patterns

#

Regex in Terraform often needs backslashes:

# ❌ Invalid
locals {
  pattern = regex("\\d+\\.\\d+", var.version)
}
 
# ✅ Double-escape: \\ for HCL → \ for regex
locals {
  # Match digits.digits (e.g., "5.60")
  pattern = regex("\\d+\\.\\d+", var.version)
}

Common regex escapes in HCL:

RegexIn HCL string
\d (digit)"\\d"
\. (literal dot)"\\."
\s (whitespace)"\\s"
\w (word char)"\\w"
\\ (literal backslash)"\\\\\\\\"

Solution 5: Template Files

#

For complex templates with many backslashes, use templatefile():

# template.ps1
$path = "C:\Users\admin"
Get-Process | Where-Object { $_.CPU -gt 100 }
 
# main.tf — templatefile reads the file as-is (no HCL escaping)
locals {
  script = templatefile("${path.module}/template.ps1", {
    admin_user = var.admin_user
  })
}

Hands-On Courses

#

Conclusion

#

HCL only allows \\, \", \n, \r, \t, and \uNNNN as escape sequences. For Windows paths, double the backslashes or use forward slashes. For complex strings with many special characters, use heredocs or templatefile().

#Terraform#Troubleshooting#DevOps#Error Fix#Infrastructure as Code

Share this article