instructure/canvas-lms · error · Lti::OAuth2::InvalidTokenError

Developer Key is not active or available in this environment

Error message

Developer Key is not active or available in this environment

What it means

Guard in Lti::IMS::AccessTokenHelper#validate_access_token!: the presented LTI 2 access token's developer key is inactive or unavailable in this environment (e.g. not activated, wrong shard/environment), so Lti::OAuth2::InvalidTokenError is raised and the caller renders 401.

Solutions

  1. Activate the developer key for this environment/account
  2. Request a fresh access token bound to an active key instead of a stale one
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at app/controllers/lti/ims/access_token_helper.rb:30 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/405bb11861226b85. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/lti/ims/access_token_helper.rb:30

# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

module Lti::IMS::AccessTokenHelper
  def authorized_lti2_tool
    validate_access_token!
    true
  rescue Lti::OAuth2::InvalidTokenError
    render_unauthorized_action
  end

  def validate_access_token!
    access_token.validate!
    raise Lti::OAuth2::InvalidTokenError "Developer Key is not active or available in this environment" if developer_key && !developer_key.usable?
  rescue Lti::OAuth2::InvalidTokenError
    raise
  rescue => e
    raise Lti::OAuth2::InvalidTokenError, e
  end

  def access_token
    @_access_token ||= begin
      access_token = AuthenticationMethods.access_token(request)
      access_token && Lti::OAuth2::AccessToken.from_jwt(
        aud: request.host,
        jwt: access_token
      )
    end
  end

  def oauth2_request?
    pattern = /^Bearer /

View on GitHub (pinned to 1c9f0bb801)