This error occurs when Terraform's fileset() function receives a malformed glob pattern. Terraform glob patterns follow POSIX syntax, and certain pattern combinations are invalid or unsupported, causing the configuration parsing to fail.
Fixes Error: Invalid path glob pattern
# Match all files in a directory
fileset(path.module, "files/*")
# Match files with specific extension
fileset(path.module, "*.tf")
# Recursively match files in all subdirectories
fileset(path.module, "files/**")
# Match specific files using brace expansion
fileset(path.module, "files/{hello,world}.txt")# Match all files in a directoryfileset(path.module, "files/*")# Match files with specific extensionfileset(path.module, "*.tf")# Recursively match files in all subdirectoriesfileset(path.module, "files/**")# Match specific files using brace expansionfileset(path.module, "files/{hello,world}.txt")Error: Invalid path glob pattern
Terraform uses glob patterns to match files in the fileset() function, commonly used with for_each to create multiple resources. A glob pattern is invalid when it violates POSIX syntax rules. For example, patterns like `/path**` are malformed because `**` must appear with proper path delimiters. The fileset() function is evaluated during configuration parsing (before Terraform takes any actions), so pattern errors prevent the configuration from being parsed at all. Invalid patterns typically include incorrect double-wildcard usage, mismatched brackets in brace expansion, or patterns that reference non-existent base paths.
Review your fileset() call and ensure the pattern follows POSIX glob rules. Common patterns:
# Match all files in a directory
fileset(path.module, "files/*")
# Match files with specific extension
fileset(path.module, "*.tf")
# Recursively match files in all subdirectories
fileset(path.module, "files/**")
# Match specific files using brace expansion
fileset(path.module, "files/{hello,world}.txt")Double-check that your pattern doesn't contain syntax errors like unmatched brackets or improper wildcard usage.
If you intended to match files recursively, ensure your pattern uses the correct syntax:
# WRONG - this is invalid
fileset(path.module, "/configs**")
# CORRECT - recursive matching
fileset(path.module, "configs/**")
# Also correct - matches everything in a directory recursively
fileset(path.module, "**")The key rule: ** must be surrounded by proper path delimiters. Use /path*/** instead of /path**.
Always use path.module as the base path for fileset(). This ensures Terraform correctly resolves paths relative to your module:
# Correct
resource "local_file" "configs" {
for_each = fileset(path.module, "configs/*")
filename = each.value
content = "..."
}
# Also works in subdirectories
for_each = fileset("${path.module}/templates", "*.tpl")Don't use absolute paths or relative paths without proper module context.
Run terraform validate to catch pattern errors early:
terraform validateIf validation still fails, the error message will show the exact pattern that's invalid. Use that feedback to refine your glob pattern syntax.
If you're using a glob pattern from a shell script or other tool, remember that Terraform glob syntax is slightly different:
# Shell: uses character ranges
files/[abc].txt
# Terraform: same syntax works
fileset(path.module, "files/[abc].txt")
# Shell: uses extended globs (with shopt globstar)
files/** (in zsh/bash 4+)
# Terraform: always supports ** for recursion
fileset(path.module, "files/**")Wrap your pattern in quotes to avoid shell expansion when running terraform commands.
The fileset() function is evaluated during configuration parsing, not during apply, so it can only match files that already exist on disk before Terraform runs. This is important if you're generating files during apply and expecting to match them with fileset()—that won't work. For matching files that might not exist yet, consider using the local_file provider or data sources instead. If you need to match directories (not just files), the built-in fileset() function doesn't support that; you'd need to use the third-party terraform-provider-glob. When using brace expansion in patterns, remember that Terraform doesn't perform shell-like expansion—the pattern is passed directly to the glob matcher. Always test your patterns in a small configuration first before applying them to production resources.