hashicorp/terraform · error · ErrInvalidModuleSource

not a valid registry module source

Error message

not a valid registry module source

What it means

ErrInvalidModuleSource is returned by regsrc.ParseModuleSource (and related parsers) when a module source string does not match the Terraform Registry format '<namespace>/<name>/<provider>[//<subpath>]'. The grammar is defined by nameSubRe (alphanumeric, max 64 chars, hyphens/underscores only in non-leading/trailing positions) and providerSubRe (lowercase alphanumeric). github.com and bitbucket.org hosts are explicitly disallowed because Terraform special-cases them.

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 d32a084675)

Solutions

  1. Reformat the source as '<host>/<namespace>/<name>/<provider>[//<subpath>]' with a lowercase provider and valid namespace/name characters.
  2. If you meant a Git source, use the git:: prefix or a full git URL instead of a registry shorthand.
  3. For github.com/bitbucket.org sources, use the native VCS source syntax, not the registry parser.
  4. Validate the source string with regsrc.NameRe / ProviderRe before passing it in.

Example fix

// before
m, err := regsrc.ParseModuleSource("Terraform-AWS-modules/vpc/aws")

// after — lowercase provider, valid namespace
m, err := regsrc.ParseModuleSource("terraform-aws-modules/vpc/aws")
Defensive patterns

Strategy: validation

Validate before calling

// Validate before parsing
if !regsrc.NameRe.MatchString(namespace) || !regsrc.ProviderRe.MatchString(provider) {
    return fmt.Errorf("namespace/provider format invalid")
}

Type guard

func isValidRegistrySource(s string) bool {
    // strip optional host prefix, then check moduleSourceRe
    _, err := regsrc.ParseModuleSource(s)
    return err == nil
}

Try / catch

m, err := regsrc.ParseModuleSource(src)
if err != nil {
    // fall back to VCS/git source parsing, or surface a clear error
    return fmt.Errorf("%q is not a valid registry module source (use namespace/name/provider): %w", src, err)
}

Prevention

When it happens

Trigger: Calling ParseModuleSource / ParseModuleSourceWithHost with a string that has the wrong number of segments, invalid characters, uppercase provider name, or a disallowed host. The regex moduleSourceRe fails to match.

Common situations: Typos in the source = line of a module block; using a bare GitHub 'org/repo' shorthand where a fully-qualified registry source is required; mixing up the order of namespace/name/provider; including a host prefix that resolves to github.com/bitbucket.org.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/d222037db1e5dc30. Report an issue: GitHub.