instructure/canvas-lms · warning

Unable to read setting: #

Error message

Unable to read setting: #{e}

What it means

Setting.get reads values from the settings table, but during early boot (rake tasks, initializers, db:create) the database or settings table may not exist yet. Canvas rescues ActiveRecord::StatementInvalid / ConnectionNotEstablished, logs 'Unable to read setting: ...', and falls back to the provided default. It is a graceful-degradation warning, not a fatal failure.

Solutions

  1. Run `bundle exec rake db:migrate` so the settings table exists before code that reads Settings
  2. Ensure DATABASE_URL/database.yml is correct and the database server is reachable
  3. Defer Setting.get calls out of boot/initializers until after DB initialization, or pass an explicit default
  4. If it only appears during asset precompile or db:create, it is expected noise — the default is used

Example fix

# before (initializer runs before DB exists)
TIMEOUT = Setting.get('request_timeout', 30).to_i

# after: defer reading until first use
def self.request_timeout
  @request_timeout ||= Setting.get('request_timeout', 30).to_i
end
Defensive patterns

Strategy: fallback

Validate before calling

begin
  ActiveRecord::Base.connection.execute('SELECT 1 FROM settings LIMIT 1')
rescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished
  # DB not ready; use default
end

Type guard

def settings_available?
  ActiveRecord::Base.connected? &&
    ActiveRecord::Base.connection.table_exists?(:settings)
rescue ActiveRecord::ConnectionNotEstablished
  false
end

Try / catch

begin
  value = Setting.get('my_setting', nil)
rescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished
  value = DEFAULT_MY_SETTING
end

Prevention

When it happens

Trigger: Calling Setting.get (often indirectly from initializers, feature flags, or config loading) before migrations have run, when the settings table doesn't exist, or when no database connection is established (e.g. during assets:precompile or db setup tasks).

Common situations: Fresh Canvas checkout without db:migrate; running yarn/webpack builds that boot Rails without a configured DATABASE_URL; CI steps that load the environment before creating the database;短暂 DB outage during boot.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at app/models/setting.rb:48

                     elsif expires_in
                       # ignore the in-proc cache, but check redis; it will have been properly
                       # cleared by whoever set it, they just have no way to clear the in-proc cache
                       @all_settings = MultiCache.fetch("all_settings", &fetch)
                     else
                       # use both caches
                       @all_settings ||= MultiCache.fetch("all_settings", &fetch)
                     end

      if all_settings.key?(name)
        all_settings[name]&.to_s
      else
        Setting.set(name, default) if set_if_nx
        default&.to_s
      end
    end
  rescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished => e
    # the db may not exist yet
    Rails.logger&.warn("Unable to read setting: #{e}")
    default&.to_s
  end

  # Note that after calling this, you should send SIGHUP to all running Canvas processes
  def self.set(name, value, secret: nil)
    s = Setting.where(name:).first_or_initialize
    s.value = value&.to_s
    s.secret = secret unless secret.nil?
    s.save!
    cache.delete(name)
    @all_settings = nil
    MultiCache.delete("all_settings")

    if defined?(Rails::Console)
      message = Setting.get("setting_set_sighup_required_message", "** NOTE: After calling `Setting.set`, SIGHUP must be sent to all Canvas processes **")
      Rails.logger.info(message)
    end
  end

View on GitHub (pinned to 1c9f0bb801)