Introduction:
This article addresses a module source parsing error encountered during Terraform runs when referencing subdirectories within version control repositories or archive-based module sources.
Problem:
Terraform runs fail with the following error:
terraform: Failed to parse source address: tfe_hostname/tfe/monitoring/aws//modules/aws/sns: error="remote package address may not have a sub-path"
This error appears when attempting to reference a module in a subdirectory of a version-controlled or packaged module source.
Applies to:
Terraform Enterprise (TFE)
Terraform Cloud for Business (TFC)
Terraform CLI
Environment:
Module source hosted in a version control system (e.g., Git) Terraform configuration referencing submodules.
Cause:
Terraform uses the double-slash (//) syntax to specify a subdirectory within a version control repository or archive package. This syntax is valid for:
Git repositories
HTTP(S) URLs
GitHub/GitLab
S3-hosted
ZIP files
Terraform Registry
Terraform supports modules located in subdirectories of a repository or archive using the special // syntax.
✅ Valid use of //:
module "example" { source = "git::https://example.com/terraform-modules.git//modules/vpc" }
❌ Invalid use:
module "example" { source = "tfe_hostname/tfe/monitoring/aws//modules/aws/sns" }
This fails because the source is not prefixed with a valid protocol (e.g., git::, https::, etc.), so Terraform doesn’t know how to interpret //.
Overview of Possible Solutions:
Whether // is needed depends on the source type. This section summarizes when to use it, and when not to.
Solutions:
Solution 1: Use // Only When Required
You must use // for subdirectories when the module is in:
Source Type | // Required for Subdirectories? | Example |
---|---|---|
Git Repos | ✅ Yes | git::https://github.com/org/repo.git//modules/s3 |
ZIP Archives | ✅ Yes | https://example.com/module.zip//vpc |
S3/GCS Archives | ✅ Yes | s3::https://s3.example.com/modules.zip//submodule |
HTTP(S) Archive | ✅ Yes | https://modules.example.com/archive.zip//vpc |
You do not need (or must not use) // for:
Source Type | // Usage | Example |
---|---|---|
Terraform Registry | ❌ Not supported | source = "hashicorp/consul/aws" |
Local Paths | ❌ Not needed | source = "./modules/vpc" |
Registry with hostname | ❌ Not supported | source = "app.terraform.io/org/module/aws" |
If // is used in these types, you’ll encounter the “may not have a sub-path” error.
Solution 2: Add a VCS Prefix (git::, hg::, etc.)
In this error:
source = "tfe_hostname/tfe/monitoring/aws//modules/aws/sns"
Terraform doesn’t recognize this as a VCS source.
Fix it by explicitly declaring it as a Git source:
source = "git::https://tfe_hostname/tfe/monitoring/aws.git//modules/aws/sns"
Ensure the .git extension is included. Add query params (e.g., ?ref=v1.0.0) after the subdirectory:
source = "git::https://tfe_hostname/repo.git//modules/sns?ref=main"
Solution 3: Use Separate Repository (Optional)
If subdirectories cause complexity or errors, split the module into its own repository:
source = "git::https://tfe_hostname/modules/aws-sns.git"
This avoids needing the // sub-path.
Outcome:
After correcting the source address:
Run terraform init to verify the module downloads correctly. Run terraform plan to ensure there are no further errors.
If the issue persists, inspect:
Whether the repository is accessible If the subdirectory exists If source formatting aligns with supported Terraform syntax
Additional Information:
Terraform Docs: Module Sources
Modules in Package Subdirectories
Module Versioning and the ref Argument