{"record":{"id":"12dea44923b88cc1","repo":"hashicorp/terraform","slug":"errinvalidmodulesource","errorCode":"ErrInvalidModuleSource","errorMessage":"not a valid registry module source","messagePattern":"not a valid registry module source","errorType":"exception","errorClass":"ErrInvalidModuleSource","httpStatus":null,"severity":"error","filePath":"internal/registry/regsrc/module.go","lineNumber":17,"sourceCode":"// Copyright IBM Corp. 2014, 2026\n// SPDX-License-Identifier: BUSL-1.1\n\npackage regsrc\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\tsvchost \"github.com/hashicorp/terraform-svchost\"\n\t\"github.com/hashicorp/terraform/internal/addrs\"\n)\n\nvar (\n\tErrInvalidModuleSource = errors.New(\"not a valid registry module source\")\n\n\t// nameSubRe is the sub-expression that matches a valid module namespace or\n\t// name. It's strictly a super-set of what GitHub allows for user/org and\n\t// repo names respectively, but more restrictive than our original repo-name\n\t// regex which allowed periods but could cause ambiguity with hostname\n\t// prefixes. It does not anchor the start or end so it can be composed into\n\t// more complex RegExps below. Alphanumeric with - and _ allowed in non\n\t// leading or trailing positions. Max length 64 chars. (GitHub username is\n\t// 38 max.)\n\tnameSubRe = \"[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?\"\n\n\t// providerSubRe is the sub-expression that matches a valid provider. It\n\t// does not anchor the start or end so it can be composed into more complex\n\t// RegExps below. Only lowercase chars and digits are supported in practice.\n\t// Max length 64 chars.\n\tproviderSubRe = \"[0-9a-z]{1,64}\"\n\n\t// moduleSourceRe is a regular expression that matches the basic","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/registry/regsrc/module.go#L1-L35","documentation":"ErrInvalidModuleSource is a sentinel from the registry source parser (regsrc), returned by NewModule when the optional host prefix is present but is either not a valid friendly host or is one of the disallowed special-case hosts (github.com, bitbucket.org) that Terraform treats as direct VCS sources, not registry hosts.","triggerScenarios":"Returned at internal/registry/regsrc/module.go:88 inside NewModule when host != \"\" and the parsed FriendlyHost is either !h.Valid() or disallowed[h.Display()] is true. The disallowed set is {github.com, bitbucket.org}.","commonSituations":"Writing a module source like `github.com/foo/bar/baz` expecting registry semantics, or `[github.com]/namespace/name/provider`. Malformed host with invalid characters. Confusing a Git source (`github.com/user/repo`) with a registry source (`hostname/namespace/name/provider`).","solutions":["For GitHub/Bitbucket, use the direct Git source form: `source = \"git::https://github.com/USER/REPO.git\"` or the shorthand `github.com/USER/REPO`, not as a registry host.","For a registry module, drop the disallowed host or use a real registry hostname (e.g. `terraform.example.com/namespace/name/provider`).","Validate the host string contains only allowed hostname characters and a real TLD.","Double-check moduleSourceRe format: namespace/name/provider with optional //submodule."],"exampleFix":"// before (treats github.com as registry host -> ErrInvalidModuleSource)\nmodule \"x\" {\n  source = \"github.com/myorg/network/vpc\"\n}\n// after (explicit git source)\nmodule \"x\" {\n  source = \"git::https://github.com/myorg/network.git//vpc?ref=v1.2.0\"\n}","handlingStrategy":"validation","validationCode":"// Pre-validate a registry module source before NewModule.\nvar regSrcRe = regexp.MustCompile(`^([A-Za-z0-9.-]+\\.[A-Za-z]{2,}/)?[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?/[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?/[0-9a-z]{1,64}(//.*)?$`)\nfunc looksLikeRegistry(src string) bool { return regSrcRe.MatchString(src) }","typeGuard":"func isInvalidModuleSource(err error) bool {\n    return errors.Is(err, regsrc.ErrInvalidModuleSource)\n}","tryCatchPattern":"m, err := regsrc.NewModule(host, ns, name, provider, sub)\nif errors.Is(err, regsrc.ErrInvalidModuleSource) {\n    if host == \"github.com\" || host == \"bitbucket.org\" {\n        // user meant a direct git source\n        return gitSource(host, ns, name)\n    }\n    return fmt.Errorf(\"invalid registry host %q\", host)\n}","preventionTips":["Never use github.com/bitbucket.org as a registry host prefix; use direct git sources for those.","Validate module source strings with moduleSourceRe before parsing.","Document the namespace/name/provider format for your team."],"tags":["registry","module","source-string","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}