go-exec-format-doctor

September 6, 2026 ยท View on GitHub

GitHub Actions architecture gate

Copy this workflow to reject a PR when its Linux binary was built for an architecture that does not match the ubuntu-latest runner:

name: Binary architecture gate

on:
  pull_request:

permissions:
  contents: read

jobs:
  binary-architecture:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
          cache: true

      - name: Build binary
        run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o dist/my-service ./cmd/my-service

      - name: Verify binary format and architecture
        uses: soul-sol/go-exec-format-doctor@v1
        with:
          path: dist/my-service

The action exports verdict, format, target, and report_json. It preserves the CLI's exit codes, so mismatches, archives, and unknown formats fail the job; compatible binaries and conditionally runnable shebang scripts pass.

Go Reference

Diagnose exec format error and binary architecture mismatches without running the file.

go-exec-format-doctor reads local file headers and reports:

  • ELF, Mach-O, universal Mach-O, and PE target architectures
  • shebang scripts and their requested interpreter
  • ar and ZIP archives that are not directly executable
  • truncated or unknown headers
  • the current host OS and architecture
  • a specific pure-Go rebuild command when a binary does not match the host

It does not execute, modify, upload, or make network requests with the inspected file. It does not determine whether a file is safe or malicious.

Install

Download the archive for your platform from GitHub Releases, verify it against checksums.txt, and place the binary on your PATH.

Or build from source with Go 1.23 or newer:

go install github.com/soul-sol/go-exec-format-doctor/cmd/go-exec-format-doctor@latest

The module and command documentation are indexed on pkg.go.dev.

Use

go-exec-format-doctor ./my-service

Example mismatch:

format: elf
target: linux/amd64
host: linux/arm64
verdict: mismatch
summary: elf binary targets linux/amd64 but this host is linux/arm64
next: GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build

Machine-readable output:

go-exec-format-doctor --json ./my-service

Suppress the optional further-help link:

go-exec-format-doctor --quiet ./my-service

Exit codes:

CodeMeaning
0compatible binary or conditionally runnable script
1architecture/OS mismatch, archive, or unknown format
2invalid CLI input, unreadable path, or output failure

What the verdict means

  • compatible: the file header includes the current OS and architecture.
  • mismatch: the file header targets another OS or architecture.
  • conditional: a script has a shebang, but the interpreter is not probed.
  • not-executable: the file is an archive container.
  • unknown: the header is truncated, corrupt, or not recognized.

Header compatibility is not a full runtime guarantee. Dynamic libraries, permissions, mount flags, kernel features, CGO dependencies, and interpreter availability can still prevent execution.

Going further

If you want to prevent architecture mismatches in CI, the USD 29 Go/Linux Cross-Architecture CI Starter Kit adds tested AMD64, ARM64, and 386 workflows, compile reports, and optional QEMU smoke tests. The free doctor remains complete and does not require the kit.

Development

go test -race -shuffle=on -count=1 ./...
go vet ./...
golangci-lint run ./...

See CONTRIBUTING.md for scope and verification requirements.

License

MIT. See LICENSE.