hashicorp/terraform · error · ErrInvalidModuleSource

ErrInvalidModuleSource

ErrInvalidModuleSource

Error message

not a valid registry module source

What it means

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.

Source

Thrown at internal/registry/regsrc/module.go:17

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1

package regsrc

import (
	"errors"
	"fmt"
	"regexp"
	"strings"

	svchost "github.com/hashicorp/terraform-svchost"
	"github.com/hashicorp/terraform/internal/addrs"
)

var (
	ErrInvalidModuleSource = errors.New("not a valid registry module source")

	// nameSubRe is the sub-expression that matches a valid module namespace or
	// name. It's strictly a super-set of what GitHub allows for user/org and
	// repo names respectively, but more restrictive than our original repo-name
	// regex which allowed periods but could cause ambiguity with hostname
	// prefixes. It does not anchor the start or end so it can be composed into
	// more complex RegExps below. Alphanumeric with - and _ allowed in non
	// leading or trailing positions. Max length 64 chars. (GitHub username is
	// 38 max.)
	nameSubRe = "[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?"

	// providerSubRe is the sub-expression that matches a valid provider. It
	// does not anchor the start or end so it can be composed into more complex
	// RegExps below. Only lowercase chars and digits are supported in practice.
	// Max length 64 chars.
	providerSubRe = "[0-9a-z]{1,64}"

	// moduleSourceRe is a regular expression that matches the basic

View on GitHub (pinned to c9def3e214)

Solutions

  1. 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.
  2. For a registry module, drop the disallowed host or use a real registry hostname (e.g. `terraform.example.com/namespace/name/provider`).
  3. Validate the host string contains only allowed hostname characters and a real TLD.
  4. Double-check moduleSourceRe format: namespace/name/provider with optional //submodule.

Example fix

// before (treats github.com as registry host -> ErrInvalidModuleSource)
module "x" {
  source = "github.com/myorg/network/vpc"
}
// after (explicit git source)
module "x" {
  source = "git::https://github.com/myorg/network.git//vpc?ref=v1.2.0"
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate a registry module source before NewModule.
var 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}(//.*)?$`)
func looksLikeRegistry(src string) bool { return regSrcRe.MatchString(src) }

Type guard

func isInvalidModuleSource(err error) bool {
    return errors.Is(err, regsrc.ErrInvalidModuleSource)
}

Try / catch

m, err := regsrc.NewModule(host, ns, name, provider, sub)
if errors.Is(err, regsrc.ErrInvalidModuleSource) {
    if host == "github.com" || host == "bitbucket.org" {
        // user meant a direct git source
        return gitSource(host, ns, name)
    }
    return fmt.Errorf("invalid registry host %q", host)
}

Prevention

When it happens

Trigger: 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}.

Common situations: 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`).

Related errors


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