hashicorp/terraform · error

cannot hash package at %s

Error message

cannot hash package at %s

What it means

PackageHashV1 (and the public Hash/MatchesHash) can only hash a provider package whose contents are readable on the local filesystem, i.e. a PackageLocalDir or PackageLocalArchive. The type switch's default branch returns this error for any other PackageLocation because there is nothing local to read. This contract is documented on Hash(): non-local locations always error. It is an invariant violation, not a runtime/network condition.

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

Solutions

  1. Download and materialize the package first so its location becomes PackageLocalArchive or PackageLocalDir before calling Hash().
  2. If you already have a local directory, wrap it as PackageLocalDir(path); if you have a zip file, wrap it as PackageLocalArchive(path).
  3. Narrow on the concrete location type with a type switch and only call Hash() for the two hashable cases.

Example fix

// before
meta, _ := src.PackageMeta(ctx, p, v, plat)
want, _ := meta.Hash() // errors: meta.Location is PackageHTTPURL

// after
// install/download first; installer.rewritePackageLocalArchive yields a local archive
archivePath, _ := installer.DownloadAndUnpack(ctx, meta, cacheDir)
local := getproviders.PackageLocalArchive(archivePath)
want, err := getproviders.PackageHash(local)
Defensive patterns

Strategy: type-guard

Validate before calling

// Only local archive/dir locations are hashable.
switch loc.(type) {
case getproviders.PackageLocalArchive, getproviders.PackageLocalDir:
    // safe to hash
default:
    return fmt.Errorf("location %T is not locally hashable; download first", loc)
}

Type guard

func isHashablePackageLocation(loc getproviders.PackageLocation) bool {
    switch loc.(type) {
    case getproviders.PackageLocalArchive, getproviders.PackageLocalDir:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling PackageHash(loc) / PackageHashV1(loc) / PackageMeta.Hash() with a location that is a PackageHTTPURL (download URL not yet fetched) or a PackageLocalURL (unpacked-but-not-materialized). Commonly hit when hashing a PackageMeta returned by Source.PackageMeta() before the installer downloads and rewrites the location to a local archive/dir.

Common situations: Test helpers that build PackageMeta with an HTTP location and then call MatchesHash; refactors that moved hashing before the download/install step; code that iterates Source results and tries to verify hashes up front.

Related errors


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