Most CLI failures fall into a small number of categories. The CLI prints the exact API error envelope on failure (`error.code`, `error.message`), so the message itself usually tells you which bucket you're in. This guide maps the common ones to their fixes.
OAuth client ID is not set
Released binaries have the OAuth client ID baked in at build time. If you built from source without passing `HEXSIGN_CLI_CLIENT_ID`, `hexsign login` fails with a clear error. Two ways to fix it:
# Either bake it in at build time: make build HEXSIGN_CLI_CLIENT_ID=<your_client_id> # Or set it once at runtime: export HEXSIGN_CLI_CLIENT_ID=<your_client_id> hexsign login
hexsign login is for human users
If `HEXSIGN_CLIENT_ID` and `HEXSIGN_CLIENT_SECRET` are both set, the CLI refuses `hexsign login` with `"login is for human users; CI runs use machine credentials automatically"`. That's correct. In CI you don't need to log in — set the env vars and run the command directly.
Port 53682 is already in use
The OAuth callback listens on `localhost:53682`. If a previous flow is still hung on that port (or another tool grabbed it), `hexsign login` errors out. Pick a different port once and forget about it.
hexsign config set callback_port 53683 hexsign login
401 Unauthorized after a long break
Refresh tokens expire after a long period of inactivity. If `hexsign whoami` returns a 401, run `hexsign logout` to clear the stale refresh token from your OS keychain, then `hexsign login` again. Cached access tokens get cleared automatically.
hexsign logout hexsign login
403 forbidden — scope or blocked route
- Missing scope
- The credential doesn't have `hexsign-api/write` but the command is a mutation (regenerate, revoke, delete). Issue a new service credential with the right scope, or run the command as a user.
- Blocked route
- Service credentials can't call `/users`, `/subscriptions`, `/contact-form`, or `/service-credentials`. Those manage humans and billing — switch to a user session for those operations.
- Wrong organization
- Service credentials are organization-scoped. If you copy a credential between orgs by mistake, every call returns 403. The dashboard's CLI Tokens page shows which org each credential belongs to.
Verbose error envelopes
When a request fails the CLI surfaces the full JSON error envelope from the API. The `error.code` is the stable machine-readable string (e.g. `signing_certificate_required`); the `error.message` is the human one. When opening a support ticket, paste the whole envelope verbatim.
Still stuck?
Open a GitHub issue at the hexsign-cli repo, or email support@hexsign.io with the failing command, the redacted error envelope, and the version printed by `hexsign --version`.