hashicorp/terraform · error

cannot hash package at

Error message

cannot hash package at %s

What it means

`PackageHashV1` switches on the concrete location type and only handles `PackageLocalDir` and `PackageLocalArchive`. Any other `PackageLocation` (e.g. `PackageHTTPURL`, `PackageLocalArchive` mismatch, or a custom impl) hits the `default` and returns this error stating hashing is unsupported for that location.

Solutions

  1. Download/extract the package to a local path first, then pass `PackageLocalDir` or `PackageLocalArchive` to `PackageHashV1`.
  2. Check the location type before calling: only hash local locations.
  3. Ensure the cache directory is populated (run `terraform init`) before hash computation.

Example fix

// before
h, err := PackageHashV1(PackageHTTPURL(u)) // -> cannot hash
// after: download to cache first
path, _ := installer.DownloadAndUnpack(ctx, meta, tmpDir, nil)
h, err := PackageHashV1(PackageLocalDir(path))
Defensive patterns

Strategy: type-guard

Validate before calling

// Only hash local locations
switch loc.(type) {
case PackageLocalDir, PackageLocalArchive:
    return PackageHashV1(loc)
default:
    return "", fmt.Errorf("cannot hash remote location %s; download first", loc)
}

Type guard

// isHashableLocal reports whether loc can be hashed
func isHashableLocal(loc PackageLocation) bool {
    switch loc.(type) {
    case PackageLocalDir, PackageLocalArchive:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: `PackageHashV1(loc)` is called with a location that is neither `PackageLocalDir` nor `PackageLocalArchive`; default at hash.go:308.

Common situations: Caller attempts to hash a remote `PackageHTTPURL` directly without downloading first; a nil or empty location slipped through; an unmounted archive whose location type is not recognised.

Related errors


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

Appendix: source

Thrown at internal/getproviders/hash.go:308

		// The dirhash.HashDir result is already in our expected h1:...
		// format, so we can just convert directly to Hash.
		s, err := dirhash.HashDir(packageDir, "", dirhash.Hash1)
		return Hash(s), err

	case PackageLocalArchive:
		archivePath, err := filepath.EvalSymlinks(string(loc))
		if err != nil {
			return "", err
		}

		// The dirhash.HashDir result is already in our expected h1:...
		// format, so we can just convert directly to Hash.
		s, err := dirhash.HashZip(archivePath, dirhash.Hash1)
		return Hash(s), err

	default:
		return "", fmt.Errorf("cannot hash package at %s", loc.String())
	}
}

// Hash computes a hash of the contents of the package at the location
// associated with the reciever, using whichever hash algorithm is the current
// default.
//
// This method will change to use new hash versions as they are introduced
// in future. If you need a specific hash version, call the method for that
// version directly instead, such as HashV1.
//
// Hash can be used only with the two local package location types
// PackageLocalDir and PackageLocalArchive, because it needs to access the
// contents of the indicated package in order to compute the hash. If given
// a non-local location this function will always return an error.
func (m PackageMeta) Hash() (providerreqs.Hash, error) {
	return PackageHash(m.Location)
}

View on GitHub (pinned to d32a084675)