{"record":{"id":"580a8393dd238b75","repo":"hashicorp/terraform","slug":"cannot-check-archive-hash-for-non-archive-location","errorCode":null,"errorMessage":"cannot check archive hash for non-archive location %s","messagePattern":"cannot check archive hash for non-archive location (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/package_authentication.go","lineNumber":306,"sourceCode":"// This authentication is suitable only for PackageHTTPURL and\n// PackageLocalArchive source locations, because the unpacked layout\n// (represented by PackageLocalDir) does not retain access to the original\n// source archive. Therefore this authenticator will return an error if its\n// given localLocation is not PackageLocalArchive.\n//\n// NewPackageHashAuthentication is preferable to use when possible because\n// it uses the newer hashing scheme (implemented by function PackageHash) that\n// can work with both packed and unpacked provider packages.\nfunc NewArchiveChecksumAuthentication(platform Platform, wantSHA256Sum [sha256.Size]byte) PackageAuthentication {\n\treturn archiveHashAuthentication{platform, wantSHA256Sum}\n}\n\nfunc (a archiveHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {\n\tarchiveLocation, ok := localLocation.(PackageLocalArchive)\n\tif !ok {\n\t\t// A source should not use this authentication type for non-archive\n\t\t// locations.\n\t\treturn nil, fmt.Errorf(\"cannot check archive hash for non-archive location %s\", localLocation)\n\t}\n\n\tgotHash, err := PackageHashLegacyZipSHA(archiveLocation)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to compute checksum for %s: %s\", archiveLocation, err)\n\t}\n\twantHash := HashLegacyZipSHAFromSHA(a.WantSHA256Sum)\n\tif gotHash != wantHash {\n\t\treturn nil, fmt.Errorf(\"archive has incorrect checksum %s (expected %s)\", gotHash, wantHash)\n\t}\n\treturn &PackageAuthenticationResult{result: verifiedChecksum}, nil\n}\n\nfunc (a archiveHashAuthentication) AcceptableHashes() []Hash {\n\treturn []Hash{HashLegacyZipSHAFromSHA(a.WantSHA256Sum)}\n}\n\ntype matchingChecksumAuthentication struct {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/package_authentication.go#L288-L324","documentation":"Programmer-error from archiveHashAuthentication.AuthenticatePackage. NewArchiveChecksumAuthentication verifies the SHA256 of the original .zip archive, so it requires a PackageLocalArchive location. If the supplied localLocation is anything else (typically PackageLocalDir, an unpacked directory) the type assertion at line 302 fails and this error is returned. The doc on NewArchiveChecksumAuthentication states this explicitly.","triggerScenarios":"A source constructs archiveHashAuthentication and hands AuthenticatePackage a PackageLocalDir (unpacked provider) or a PackageHTTPURL (remote, which the framework never passes here). The location is not a PackageLocalArchive, so the cast `localLocation.(PackageLocalArchive)` fails.","commonSituations":"A custom Source implementation that unpacks the provider before authenticating, then wires up NewArchiveChecksumAuthentication instead of NewPackageHashAuthentication. Misuse when porting an older code path that used to verify archives but now stages directories. Calling AuthenticatePackage on a location after the framework extracted the zip.","solutions":["Switch to NewPackageHashAuthentication (the 'h1:' scheme), which works on both packed archives and unpacked directories.","If you must verify the raw archive, ensure the location passed to AuthenticatePackage is a PackageLocalArchive (i.e. authenticate before unpacking).","Reorder your pipeline so archive checksum verification happens on the staged .zip, not on the extracted dir."],"exampleFix":"// before: authenticating an unpacked dir as an archive\nauth := getproviders.NewArchiveChecksumAuthentication(platform, wantSHA)\n_, err := auth.AuthenticatePackage(unpackedDir) // PackageLocalDir\n// after: use the hash authenticator that accepts directories\nauth := getproviders.NewPackageHashAuthentication(platform, validHashes)\n_, err := auth.AuthenticatePackage(unpackedDir)","handlingStrategy":"type-guard","validationCode":"// Pick the authenticator based on the concrete location type.\nfunc pickAuth(loc getproviders.PackageLocation, want [sha256.Size]byte, hashes []providerreqs.Hash) getproviders.PackageAuthentication {\n    switch loc.(type) {\n    case getproviders.PackageLocalArchive:\n        return getproviders.NewArchiveChecksumAuthentication(platform, want)\n    default:\n        return getproviders.NewPackageHashAuthentication(platform, hashes)\n    }\n}","typeGuard":"// Guard the location type before choosing an archive authenticator.\nfunc isArchive(loc getproviders.PackageLocation) bool {\n    _, ok := loc.(getproviders.PackageLocalArchive)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Prefer NewPackageHashAuthentication which works on dirs and archives.","Authenticate archives BEFORE unpacking them.","Unit-test your Source with both PackageLocalArchive and PackageLocalDir locations."],"tags":["configuration","archive","provider","api-misuse","type-assertion"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}