instructure/canvas-lms · error · InvalidLaunch

no payload found in cache

Error message

no payload found in cache

What it means

Guard in Lti::IMS::AuthenticationController#cached_launch_with_nonce: fetch_and_delete_launch found no cached launch payload in Redis/cache for the given context + verifier, meaning the LTI launch was already consumed, expired, or the verifier is wrong. Raised as InvalidLaunch during OIDC third-party-initiated launches.

Solutions

  1. Restart the OIDC login flow to get a fresh verifier/launch payload
  2. Avoid replaying the same verifier; payloads are deleted on first use
  3. Check for clock/caching issues that expire the payload prematurely
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at app/controllers/lti/ims/authentication_controller.rb:205 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/7366e8e2be4683f5. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/lti/ims/authentication_controller.rb:205

        decoded_jwt["canvas_domain"]
      end

      # Overrides method in Lti::Concerns::ParentFrame; used by set_extra_csp_frame_ancestor!
      def parent_frame_context
        decoded_jwt["parent_frame_context"]
      end

      def context
        @context ||= begin
          model = decoded_jwt["context_type"].constantize
          model.find(decoded_jwt["context_id"])
        end
      end

      def cached_launch_with_nonce
        @cached_launch_with_nonce ||= begin
          launch_payload = fetch_and_delete_launch(context, verifier)
          raise InvalidLaunch, "no payload found in cache" if launch_payload.nil?

          Lti::Messages::JwtMessage.cached_hash_to_launch(JSON.parse(launch_payload), oidc_params[:nonce])
        end
      end

      def launch_parameters
        @launch_parameters ||= id_token.merge({
          state: oidc_params[:state],
          lti_storage_target:
        }.compact)
      end

      def lti_storage_target
        return nil unless decoded_jwt["include_storage_target"]

        Lti::PlatformStorage::FORWARDING_TARGET
      end

View on GitHub (pinned to 1c9f0bb801)