gaiad they run is the one the gaia maintainers published, or who build it themselves. Installation covers the quick path. This page covers what is behind each option.
Release artifacts
Each gaia release on GitHub (https://github.com/cosmos/gaia/releases/tag/v28.3.1, published 2026-10-01) ships:
gaiad-v28.3.1-linux-amd64andgaiad-v28.3.1-darwin-amd64: bare binaries, each with a detached signature.asc.gaiad-linux-amd64.tar.gzandgaiad-darwin-amd64.tar.gz: the same binaries in a directory with asha256sum.txt, each with a detached signature.asc.SHA256SUMS-v28.3.1.txt: SHA-256 of the binaries as extracted from the archives (./gaiad-linux-amd64/gaiad,./gaiad-darwin-amd64/gaiad).
.goreleaser.yml in the gaia repository) disables it because the static wasmvm library the Hub’s CosmWasm module links against is built for amd64 only. Operators on arm64 hosts build from source or run the amd64 image under emulation.
Check a download
Releases are signed with the Cosmos release key, published with instructions in thecosmos/security repository (https://github.com/cosmos/security/tree/main/release/gaia/signing). Fingerprint: E625 9F16 9C7B 913D BB75 DE02 5395 305D 29B8 8B32, identity Cosmos-Release <nodes@cosmoslabs.io>.
--show-keys flag prints the fingerprint of the downloaded key. Compare it against the one above before importing. The gpg --verify command must print Good signature from "Cosmos-Release <nodes@cosmoslabs.io>" with that fingerprint. The WARNING: This key is not certified with a trusted signature line that follows is not a failure. It only means your local GNU Privacy Guard (GPG) has not been told to trust the key. The sha256sum -c command prints ./gaiad-linux-amd64/gaiad: OK. Do not run a binary whose signature fails, is from another key, or whose checksum does not match. The bare binaries verify the same way with their own .asc.
The extracted binary is a static position-independent executable (PIE), so it runs on any x86-64 Linux without extra libraries. The file gaiad command reports static-pie linked.
Docker image
The release workflow also publishesghcr.io/cosmos/gaia with the version as the tag:
Dockerfile in the repository) builds gaiad on golang:1.25.7-alpine with a statically linked musl wasmvm. It copies only the binary into an Alpine base and runs as user nonroot (uid 1025). It exposes 26656, 26657, 1317, and 9090. Its entrypoint is gaiad start, so arguments to docker run are appended to start. Any other subcommand needs --entrypoint gaiad, as in the version check above. Mount the home directory at a path the nonroot user can write and pass --home. Run gaiad as a service covers running it under systemd or compose.
Build from source
make install target runs go install with the repository’s build flags and places gaiad in $GOPATH/bin. The make build target puts it in build/ instead. The Makefile refuses Go older than 1.25 (check_version). Version v28.3.1 was released with Go 1.25.7. Default build tags are netgo and ledger. The ledger tag needs gcc, and LEDGER_ENABLED=false make install drops it on hosts without a compiler. The linker flags stamp the version, commit, build tags, and CometBFT version into the binary. That is what gaiad version --long prints. The -trimpath flag strips local paths. Setting GAIA_BUILD_OPTIONS=nostrip keeps debug symbols. Setting LINK_STATICALLY=true with BUILD_TAGS=muslc and a musl wasmvm produces the static binary the Docker image uses.
A source build on your own machine gives the same version and commit as the release but not a byte-identical file, because the release is cross compiled in a container with a static wasmvm. Treat source builds as trusted because you built them from a checked-out tag. Treat release downloads as trusted because the signature verifies.
How releases are built
Releases are produced by.github/workflows/release.yml, which runs goreleaser inside the goreleaser-cross image. The configuration is in .goreleaser.yml: CGO_ENABLED=1, tags netgo,ledger,static_wasm, -trimpath -mod=readonly, a mod_timestamp fixed to the commit time, and the same version ldflags as the Makefile. That configuration builds the macOS binaries. The Linux binary is a static musl build without the ledger tag. The make goreleaser-build-local target runs that configuration on a workstation with Docker (release --snapshot --skip=publish). It is the way to reproduce the release build environment. Expect it to run for a long time.
Verify
version: v28.3.1, commit: b7f8b81b followed by the full hash, build_tags: netgo,muslc for the Linux release binary (netgo,ledger,static_wasm for macOS, netgo,ledger for a default source build), go: go version go1.25.7, and cosmos_sdk_version: v0.53.4. A different commit for the same version string means the binary was not built from the release tag.
Next
- Installation to put the verified binary in place.
- Versions for the dependency versions in a Hub release.
- Upgrade a node for verifying the next release before Cosmovisor switches to it.