hashicorp/terraform · error

invalid source address: %s

Error message

invalid source address: %s

What it means

The terminal fallback in detectRemoteSourceShorthands (internal/getmodules/moduleaddrs/detect_remote_shorthands.go:93). It fires when the source is not already a valid URL with a scheme AND none of the registered detectors (detectGitHub, detectGit, detectBitBucket, detectGCS, detectS3, detectAbsFilePath) recognize it. In other words, the string matches no known local-path, registry, URL, or shorthand form, so Terraform gives up.

Source

Thrown at internal/getmodules/moduleaddrs/detect_remote_shorthands.go:93

			// have to ensure the path isn't escaped.
			u.RawPath = u.Path

			result = u.String()
		}

		// Preserve the forced getter if it exists. We try to use the
		// original set force first, followed by any force set by the
		// detector.
		if getForce != "" {
			result = fmt.Sprintf("%s::%s", getForce, result)
		} else if detectForce != "" {
			result = fmt.Sprintf("%s::%s", detectForce, result)
		}

		return result, nil
	}

	return "", fmt.Errorf("invalid source address: %s", src)
}

func getForcedSourceType(src string) (string, string) {
	var forced string
	if ms := forcedRegexp.FindStringSubmatch(src); ms != nil {
		forced = ms[1]
		src = ms[2]
	}

	return forced, src
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. For a registry module, use the full three- or four-part address: namespace/name/system (e.g. hashicorp/consul/aws).
  2. For a remote URL, include the scheme: https://..., git::ssh://..., s3::https://....
  3. For a local module, prefix the path with ./ or ../ (e.g. ./modules/network).
  4. Double-check the spelling of every path segment; a single typo can cause every detector to miss.

Example fix

// before
module "x" { source = "hashicorp-consul" }
// after
module "x" { source = "hashicorp/consul/aws" }
Defensive patterns

Strategy: validation

Validate before calling

// Reject sources that no detector or parser can handle before calling detect.
func looksLikeValidSource(s string) bool {
	for _, p := range []string{"./", "../", ".\\", "..\\"} {
		if strings.HasPrefix(s, p) {
			return true
		}
	}
	if u, err := url.Parse(s); err == nil && u.Scheme != "" {
		return true
	}
	parts := strings.Split(s, "/")
	// registry: NAMESPACE/NAME/SYSTEM (3) or HOST/NAMESPACE/NAME/SYSTEM (4)
	return len(parts) == 3 || len(parts) == 4
}

Try / catch

addr, err := moduleaddrs.ParseModuleSource(src)
if err != nil {
    return fmt.Errorf("%s is not a valid module source (use namespace/name/system, a URL, or a ./local path): %w", src, err)
}

Prevention

When it happens

Trigger: A module source that is a bare word (e.g. 'consul'), a typo'd registry address ('hashicorp/consul'), a URL missing its scheme ('github.com/user/repo' without the github detector matching due to malformed structure), or any string that fails every detector.

Common situations: Forgetting the registry address format (namespace/name/system vs. just name); omitting the URL scheme; typos in hostnames; referencing a module by a friendly name that is neither a registry entry nor a path.

Related errors


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