Repository: bazelbuild/bazel
Issue: bzlmod integrity error messages are inaccurate and confusing
Labels: type: bug
P2
team-ExternalDeps
bad error messaging
area-Bzlmod

### Description of the bug:


It is extremely difficult to try to figure out how to add an `integrity` value to a Bzlmod override, and the logs are generally completely incorrect for suggestions.

I add an archive override:
```
archive_override(
    module_name = "gazelle",
    patches = [
        "//patches:bzlmod.patch",
    ],
    patch_strip = 1,
    strip_prefix = "bazel-gazelle-master",
    urls = ["https://github.com/bazelbuild/bazel-gazelle/archive/refs/heads/master.zip"],
)
```
The logs output:
```
DEBUG: Rule 'gazelle~override' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "a29f02861da70387de1193e17acdc9902aa3636ac3979a18e8d52289c23df676"
```
I try this, but get the error:
```
Error in archive_override: archive_override() got unexpected keyword argument 'sha256'
```
So, I then look up the `archive_override` fields, and add `integrity` field, to get the following errors:
```
Error in download_and_extract: Checksum error in repository @gazelle~override: Invalid SHA-256 SRI checksum 'sha256-a29f02861da70387de1193e17acdc9902aa3636ac3979a18e8d52289c23df676'
```

I try to go look on https://github.com/bazelbuild/bazel-central-registry/tree/main/modules to find the formatting of existing integrity values, but can't find anything.

So I go find an example: https://github.com/meteorcloudy/bzlmod-examples/blob/main/examples/06-archive-override/MODULE.bazel, and try to attach the `integrity = "sha256-zyeBn+s3YRUpFz1NjJ3WcZI9moLg7ImxZIkAksUNPJo="`, but then the logs show this:
```
Error in download_and_extract: java.io.IOException: Error downloading [https://github.com/bazelbuild/bazel-gazelle/archive/refs/heads/master.zip] to /home/user/.cache/bazel/_bazel_tfrench/b97476d719d716accead0f2d5b93104f/external/gazelle~override/temp15987837649025287268/master.zip: Checksum was a29f02861da70387de1193e17acdc9902aa3636ac3979a18e8d52289c23df676 but wanted cf27819feb37611529173d4d8c9dd671923d9a82e0ec89b164890092c50d3c9a
ERROR: Error computing the main repository mapping: unknown error during computation of main repo mapping
```
But this isn't even the value that I added to the rule.

### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.


Add any incorrect `integrity` value to an override, and try to fix is using the error logs.

### Which operating system are you running Bazel on?


Linux

### What is the output of `bazel info release`?


release 6.0.0

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.


_No response_

### What's the output of `git remote get-url origin; git rev-parse master; git rev-parse HEAD` ?


_No response_

### Have you found anything relevant by searching the web?

I was unable to find any documentation to help fix the issue.

### Any other information, logs, or outputs that you want to share?

_No response_

Issue comments:
It looks like this might be related to https://github.com/bazelbuild/bazel/issues/17123 and https://github.com/bazelbuild/bazel/issues/17124

I think this is more urgent than P2, since a mismatching/incorrect value is printed when the integrity is wrong.
this has been helping us locally:

**in `~/bin/integrity`** (or wherever you prefer your scripts):
```bash
#!/bin/bash

#
# SRI hash generator utility from github.com/bazelbuild/bazel/issues/17803
#

set -eo pipefail

>&2 echo "Computing integrity for $1";
echo -n "sha256-";
curl -fsSL -tlsv1.2 "$1" | openssl dgst -sha256 -binary | openssl base64 -A
```

**usage:**
```
$> integrity github.com/sgammon/rules_graalvm/archive/v0.9.0.tar.gz

Computing integrity for github.com/sgammon/rules_graalvm/archive/v0.9.0.tar.gz
sha256-ljI6wbeludsa4aOIxe0fuDDUYo06tLfwlThVgyHgMRE=
```

piping the output will yield the integrity hash only, so it works with `pbcopy` on a mac:
```
$> integrity github.com/sgammon/rules_graalvm/archive/v0.9.0.tar.gz | pbcopy
Computing integrity for github.com/sgammon/rules_graalvm/archive/v0.9.0.tar.gz

# On your clipboard:
# sha256-ljI6wbeludsa4aOIxe0fuDDUYo06tLfwlThVgyHgMRE=
```
:wave:  I ran into this error. I found this really confusing. After consulting the docs and not seeing any guidance, I searched around github, but didn't find any actually using the integrity field. It is not clear at all what is wrong, and it seems like it is broken.

I asked in slack and was helpfully shown the blessed way to translate the sha sum bazel provides ([thread](https://bazelbuild.slack.com/archives/C014RARENH0/p1699633751197809)).

Improving the usability would be really helpful! Perhaps a "legacy" `sha256` field that allows it to work like `http_archive` would be fantastic.
Should be fixed in 7.0.0 (except the doc part, which is covered by https://github.com/bazelbuild/bazel/issues/17124).
A fix for this issue has been included in [Bazel 7.0.0 RC5](https://releases.bazel.build/7.0.0/rc5/index.html). Please test out the release candidate and report any issues as soon as possible. Thanks!

Pull request review comments:

Patch that resolved the issue:
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index 766eaed0864425..d96714c88e0c36 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -2158,7 +2158,7 @@
   "moduleExtensions": {
     "//:extensions.bzl%bazel_android_deps": {
       "general": {
-        "bzlTransitiveDigest": "JIUppb9cYpap/pfU76BpY/F/Qd6Qld7XVEsAa78X0T4=",
+        "bzlTransitiveDigest": "PjK+f/kxkhda9tRFlKVdGfNszPoXs7CDXZUi+ZGWGYU=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -2177,9 +2177,9 @@
     },
     "//:extensions.bzl%bazel_build_deps": {
       "general": {
-        "bzlTransitiveDigest": "JIUppb9cYpap/pfU76BpY/F/Qd6Qld7XVEsAa78X0T4=",
+        "bzlTransitiveDigest": "PjK+f/kxkhda9tRFlKVdGfNszPoXs7CDXZUi+ZGWGYU=",
         "accumulatedFileDigests": {
-          "@@//src/test/tools/bzlmod:MODULE.bazel.lock": "8d144d3e597e69c9cb6f572e9cae8333cc991ba75d61fff1c4d9bd2ad4e2d429",
+          "@@//src/test/tools/bzlmod:MODULE.bazel.lock": "10b96bd3c1eb194b0efe3a13fd06f2051abf36efb33414ad92048883ba471c7f",
           "@@//:MODULE.bazel": "016812bd09c1de57c7cbfd60192cc76e75a4f564caafc4af0a018cd66ffb0cae"
         },
         "envVariables": {},
@@ -2428,7 +2428,7 @@
     },
     "//:extensions.bzl%bazel_test_deps": {
       "general": {
-        "bzlTransitiveDigest": "JIUppb9cYpap/pfU76BpY/F/Qd6Qld7XVEsAa78X0T4=",
+        "bzlTransitiveDigest": "PjK+f/kxkhda9tRFlKVdGfNszPoXs7CDXZUi+ZGWGYU=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -2478,7 +2478,7 @@
     },
     "//tools/android:android_extensions.bzl%remote_android_tools_extensions": {
       "general": {
-        "bzlTransitiveDigest": "hL6dUUghnqmrcFrs2bvFCvxPHBnPOY3ymycjIbgRQac=",
+        "bzlTransitiveDigest": "iz3RFYDcsjupaT10sdSPAhA44WL3eDYkTEnYThllj1w=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -2505,7 +2505,7 @@
     },
     "//tools/test:extensions.bzl%remote_coverage_tools_extension": {
       "general": {
-        "bzlTransitiveDigest": "DEE4EmNqW6/brpzbLQMxPvdWKALzpq/MeZyydMFsjLI=",
+        "bzlTransitiveDigest": "cizrA62cv8WUgb0cCmx5B6PRijtr/I4TAWxg/4caNGU=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
diff --git a/tools/build_defs/repo/http.bzl b/tools/build_defs/repo/http.bzl
index b61c4046197ead..81fc3f96dc77ab 100644
--- a/tools/build_defs/repo/http.bzl
+++ b/tools/build_defs/repo/http.bzl
@@ -129,10 +129,10 @@ def _get_auth(ctx, urls):
         netrc = read_user_netrc(ctx)
     return use_netrc(netrc, urls, ctx.attr.auth_patterns)
 
-def _update_sha256_attr(ctx, attrs, download_info):
-    # We don't need to override the sha256 attribute if integrity is already specified.
-    sha256_override = {} if ctx.attr.integrity else {"sha256": download_info.sha256}
-    return update_attrs(ctx.attr, attrs.keys(), sha256_override)
+def _update_integrity_attr(ctx, attrs, download_info):
+    # We don't need to override the integrity attribute if sha256 is already specified.
+    integrity_override = {} if ctx.attr.sha256 else {"integrity": download_info.integrity}
+    return update_attrs(ctx.attr, attrs.keys(), integrity_override)
 
 def _http_archive_impl(ctx):
     """Implementation of the http_archive rule."""
@@ -155,7 +155,7 @@ def _http_archive_impl(ctx):
     workspace_and_buildfile(ctx)
     patch(ctx, auth = auth)
 
-    return _update_sha256_attr(ctx, _http_archive_attrs, download_info)
+    return _update_integrity_attr(ctx, _http_archive_attrs, download_info)
 
 _HTTP_FILE_BUILD = """\
 package(default_visibility = ["//visibility:public"])
@@ -195,7 +195,7 @@ def _http_file_impl(ctx):
     ctx.file("WORKSPACE", "workspace(name = \"{name}\")".format(name = ctx.name))
     ctx.file("file/BUILD", _HTTP_FILE_BUILD.format(downloaded_file_path))
 
-    return _update_sha256_attr(ctx, _http_file_attrs, download_info)
+    return _update_integrity_attr(ctx, _http_file_attrs, download_info)
 
 _HTTP_JAR_BUILD = """\
 load("{rules_java_defs}", "java_import")
@@ -235,7 +235,7 @@ def _http_jar_impl(ctx):
         rules_java_defs = str(Label("@rules_java//java:defs.bzl")),
     ))
 
-    return _update_sha256_attr(ctx, _http_jar_attrs, download_info)
+    return _update_integrity_attr(ctx, _http_jar_attrs, download_info)
 
 _http_archive_attrs = {
     "url": attr.string(doc = _URL_DOC),


Test patch:
diff --git a/src/test/shell/bazel/bazel_repository_cache_test.sh b/src/test/shell/bazel/bazel_repository_cache_test.sh
index 4836db5b09ebef..c6c2c38394bc4d 100755
--- a/src/test/shell/bazel/bazel_repository_cache_test.sh
+++ b/src/test/shell/bazel/bazel_repository_cache_test.sh
@@ -124,6 +124,7 @@ EOF
     zip -0 -ry "$repo2_zip" WORKSPACE fox >& $TEST_log
     repo2_name=$(basename "$repo2_zip")
     sha256=$(sha256sum "$repo2_zip" | cut -f 1 -d ' ')
+    integrity="sha256-$(cat "$repo2_zip" | openssl dgst -sha256 -binary | openssl base64 -A)"
   fi
   serve_file "$repo2_zip"
 
@@ -278,7 +279,7 @@ EOF
         //zoo:breeding-program >& $TEST_log \
     || fail "expected fetch to succeed"
 
-  expect_log "${sha256}"
+  expect_log "${integrity}"
 
   # Shutdown the server; so fetching again won't work
   shutdown_server
diff --git a/src/test/shell/bazel/workspace_resolved_test.sh b/src/test/shell/bazel/workspace_resolved_test.sh
index f3abd91f1a9912..6cbaa188d7e383 100755
--- a/src/test/shell/bazel/workspace_resolved_test.sh
+++ b/src/test/shell/bazel/workspace_resolved_test.sh
@@ -335,10 +335,10 @@ test_http_return_value() {
   touch a/f.txt
 
   zip a.zip a/*
-  expected_sha256="$(sha256sum "${EXTREPODIR}/a.zip" | head -c 64)"
+  expected_integrity="sha256-$(cat "${EXTREPODIR}/a.zip" | openssl dgst -sha256 -binary | openssl base64 -A)"
   rm -rf a
 
-  # http_archive rule doesn't specify the sha256 attribute
+  # http_archive rule doesn't specify the integrity attribute
   mkdir -p main
   cat > main/WORKSPACE <<EOF
 workspace(name = "main")
@@ -355,7 +355,7 @@ EOF
   bazel sync \
       --experimental_repository_resolved_file=../repo.bzl
 
-  grep ${expected_sha256} ../repo.bzl || fail "didn't return commit"
+  grep ${expected_integrity} ../repo.bzl || fail "didn't return integrity"
 }
 
 test_sync_calls_all() {
diff --git a/src/test/tools/bzlmod/MODULE.bazel.lock b/src/test/tools/bzlmod/MODULE.bazel.lock
index ef16ccfb6da976..80fcbbd46be616 100644
--- a/src/test/tools/bzlmod/MODULE.bazel.lock
+++ b/src/test/tools/bzlmod/MODULE.bazel.lock
@@ -621,7 +621,7 @@
     }
   },
   "moduleExtensions": {
-    "@apple_support~1.5.0//crosstool:setup.bzl%apple_cc_configure_extension": {
+    "@@apple_support~1.5.0//crosstool:setup.bzl%apple_cc_configure_extension": {
       "general": {
         "bzlTransitiveDigest": "pMLFCYaRPkgXPQ8vtuNkMfiHfPmRBy6QJfnid4sWfv0=",
         "accumulatedFileDigests": {},
@@ -644,9 +644,9 @@
         }
       }
     },
-    "@bazel_tools//tools/android:android_extensions.bzl%remote_android_tools_extensions": {
+    "@@bazel_tools//tools/android:android_extensions.bzl%remote_android_tools_extensions": {
       "general": {
-        "bzlTransitiveDigest": "hL6dUUghnqmrcFrs2bvFCvxPHBnPOY3ymycjIbgRQac=",
+        "bzlTransitiveDigest": "iz3RFYDcsjupaT10sdSPAhA44WL3eDYkTEnYThllj1w=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -671,7 +671,7 @@
         }
       }
     },
-    "@bazel_tools//tools/cpp:cc_configure.bzl%cc_configure_extension": {
+    "@@bazel_tools//tools/cpp:cc_configure.bzl%cc_configure_extension": {
       "general": {
         "bzlTransitiveDigest": "O9sf6ilKWU9Veed02jG9o2HM/xgV/UAyciuFBuxrFRY=",
         "accumulatedFileDigests": {},
@@ -694,7 +694,7 @@
         }
       }
     },
-    "@bazel_tools//tools/osx:xcode_configure.bzl%xcode_configure_extension": {
+    "@@bazel_tools//tools/osx:xcode_configure.bzl%xcode_configure_extension": {
       "general": {
         "bzlTransitiveDigest": "Qh2bWTU6QW6wkrd87qrU4YeY+SG37Nvw3A0PR4Y0L2Y=",
         "accumulatedFileDigests": {},
@@ -712,7 +712,7 @@
         }
       }
     },
-    "@bazel_tools//tools/sh:sh_configure.bzl%sh_configure_extension": {
+    "@@bazel_tools//tools/sh:sh_configure.bzl%sh_configure_extension": {
       "general": {
         "bzlTransitiveDigest": "hp4NgmNjEg5+xgvzfh6L83bt9/aiiWETuNpwNuF1MSU=",
         "accumulatedFileDigests": {},
@@ -728,9 +728,9 @@
         }
       }
     },
-    "@bazel_tools//tools/test:extensions.bzl%remote_coverage_tools_extension": {
+    "@@bazel_tools//tools/test:extensions.bzl%remote_coverage_tools_extension": {
       "general": {
-        "bzlTransitiveDigest": "DEE4EmNqW6/brpzbLQMxPvdWKALzpq/MeZyydMFsjLI=",
+        "bzlTransitiveDigest": "cizrA62cv8WUgb0cCmx5B6PRijtr/I4TAWxg/4caNGU=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -748,9 +748,9 @@
         }
       }
     },
-    "@rules_java~7.1.0//java:extensions.bzl%toolchains": {
+    "@@rules_java~7.1.0//java:extensions.bzl%toolchains": {
       "general": {
-        "bzlTransitiveDigest": "QHrMRjNPjXXgiGx8x2I1hGry4XALDWB19awlz4iYfwg=",
+        "bzlTransitiveDigest": "iUIRqCK7tkhvcDJCAfPPqSd06IHG0a8HQD0xeQyVAqw=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -1288,9 +1288,9 @@
         }
       }
     },
-    "@rules_python~0.4.0//bzlmod:extensions.bzl%pip_install": {
+    "@@rules_python~0.4.0//bzlmod:extensions.bzl%pip_install": {
       "general": {
-        "bzlTransitiveDigest": "jfaPoItGn7QX/GUEdWPqrBf5a380ATtgwvSoPQF/t/Q=",
+        "bzlTransitiveDigest": "rTru6D/C8vlaQDk4HOKyx4U/l6PCnj3Aq/gLraAqHgQ=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {