Skip to content
Latchkey

gem push "401 ... Access Denied / bad authentication" in CI

rubygems.org rejected the push because it received no valid API key. CI has no ~/.gem/credentials, so you must supply the key through the GEM_HOST_API_KEY environment variable.

What this error means

gem push fails with "Access Denied. Please sign up for an account at https://rubygems.org" or a 401, even though gem build succeeded.

gem
Pushing gem to https://rubygems.org...
Access Denied. Please sign up for an account at https://rubygems.org and verify your email address.

Common causes

No API key configured on the runner

CI containers have no stored RubyGems credentials. Without GEM_HOST_API_KEY or a credentials file, the push is anonymous and denied.

A wrong key or one lacking push scope

An expired key, a key for a different host, or a key without the push_rubygem scope all fail authentication.

How to fix it

Set GEM_HOST_API_KEY from a secret

gem reads this environment variable as the API key, so no credentials file is needed.

.github/workflows/release.yml
- run: gem push my_gem-1.2.1.gem
  env:
    GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}

Confirm the key scope and host

  1. Generate an API key with the push_rubygem scope.
  2. Use it for the matching host (rubygems.org vs a private gem server).
  3. Store it as a CI secret and reference it in the publish step.

How to prevent it

  • Supply GEM_HOST_API_KEY from a CI secret on every push.
  • Scope the API key to push and to the correct host.
  • Consider RubyGems trusted publishing (OIDC) to avoid long-lived keys.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →