title: 500 Internal Server Error - Aws::S3::Errors::AccessDenied - CarrierWave
body: <p>I am trying to upload images to S3 via CarrierWave but keep getting a 500 Internal Server Error - Aws::S3::Errors::AccessDenied. I am using the ruby gem CarrierWave to configure AWS and dotenv-rails to call and hide my credentials in a .env file. It seems my code is working properly but I am being denied permission to my bucket. This is my first time trying to integrate AWS into a project so my configuration might be off on that end. Any help would be greatly appreciated. </p>
  
  <p>I have already tried resetting my access keys and making sure my region was set properly. I even changed the region and received an error which prompted me to change it back to the correct region: "us-west-1".
  I made sure that dotenv-rails was working correctly by making sure I could fetch my credentials via the rails console. I also used 'byebug' to set a break point in my update action in my portfolio controller to manually enter the update code myself. I can see the new image I am attempting to update my portfolio item with but it always rollsback. </p>
  
  <p>portfolios_controller.rb:</p>
  
  <pre><code>class PortfoliosController &lt; ApplicationController
      before_action :set_portfolio, only: [:show, :edit, :update, :destroy]
  
      layout "portfolio"
  
      access all: [:show, :index, :javascript], user: {except: [:destroy, :new, :create, :update, :edit, :sort]}, site_admin: :all
  
      def index
          @portfolio_items = Portfolio.by_position
      end
  
    def sort
      params[:order].each do |key, value|
        Portfolio.find(value[:id]).update(position: value[:position])
      end
  
      render :index
    end
  
      def javascript
          @javascript_portfolio_items = Portfolio.javascript
      end
  
      def new
          @portfolio_item = Portfolio.new
          3.times { @portfolio_item.technologies.build }
      end
  
      def show
      end
  
      def create
      @portfolio_item = Portfolio.new(portfolio_params)
  
      respond_to do |format|
        if @portfolio_item.save
          format.html { redirect_to portfolios_path, notice: 'Portfolio item was successfully created.' }
        else
          format.html { render :new }
        end
      end
      end
  
      def edit
      end
  
      def update
              respond_to do |format|
                  if @portfolio_item.update(portfolio_params)
                      format.html { redirect_to portfolios_path, notice: 'Portfolio item was successfully updated.' }
                  else
                      format.html { render :edit }
                  end
              end
      end
  
      def destroy
          @portfolio_item.destroy
  
      respond_to do |format|
        format.html { redirect_to portfolios_url, notice: 'Portfolio item was successfully deleted.' }
      end
      end
  
      private
      # Use callbacks to share common setup or constraints between actions.
      def set_portfolio
          @portfolio_item = Portfolio.find(params[:id])
      end
  
      # Never trust parameters from the scary internet, only allow the white list through.
      def portfolio_params
          params.require(:portfolio).permit(:title, 
                                                                              :subtitle, 
                                                                              :main_image,
                                                                              :thumb_image,
                                                                              :body, 
                                                                              technologies_attributes: [:id, :name, :_destroy]
                                                                              )
      end
  
  end
  
  </code></pre>
  
  <p>carrierwave.rb:</p>
  
  <pre><code>CarrierWave.configure do |config|
    config.storage    = :aws
    config.aws_bucket = ENV.fetch('S3_BUCKET_NAME')
    config.aws_acl    = 'public-read'
    config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
    config.aws_attributes = {
      expires: 1.week.from_now.httpdate,
      cache_control: 'max-age=604800'
    }
  
     config.aws_credentials = {
      access_key_id:     ENV.fetch('AWS_ACCESS_KEY_ID'),
      secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
      region:            ENV.fetch('AWS_REGION') # Required
    }
  end 
  </code></pre>
  
  <p>portfolio_uploader.rb:</p>
  
  <pre><code>class PortfolioUploader &lt; CarrierWave::Uploader::Base
  
    storage :aws
  
    def store_dir
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  
    # Add a white list of extensions which are allowed to be uploaded.
    # For images you might use something like this:
    def extension_whitelist
      %w(jpg jpeg gif png)
    end
  
  end
  </code></pre>
  
  <p>Rails Server:</p>
  
  <pre><code>Started PATCH "/portfolios/10" for 127.0.0.1 at 2019-02-13 14:42:36 -0600
  Processing by PortfoliosController#update as HTML
    Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"rYMLuRSQkoq6Nx+4MdXulBMCaBTRZm0xAm1qVLWf9QYnZewSPFXylE/HSK/1kXliZqX+pt4J+6YPjCslcgc9AA==", "portfolio"=&gt;{"title"=&gt;"Updated", "subtitle"=&gt;"Javascript", "main_image"=&gt;#&lt;ActionDispatch::Http::UploadedFile:0x00007fe00d14f6f0 @tempfile=#&lt;Tempfile:/var/folders/8c/dyl1g215043d3hk1gzq9bz4h0000gn/T/RackMultipart20190213-59215-1dc56wv.png&gt;, @original_filename="b7jlq5pf52m11.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"portfolio[main_image]\"; filename=\"b7jlq5pf52m11.png\"\r\nContent-Type: image/png\r\n"&gt;, "thumb_image"=&gt;#&lt;ActionDispatch::Http::UploadedFile:0x00007fe00d14f678 @tempfile=#&lt;Tempfile:/var/folders/8c/dyl1g215043d3hk1gzq9bz4h0000gn/T/RackMultipart20190213-59215-1ay0r07.png&gt;, @original_filename="b7jlq5pf52m11.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"portfolio[thumb_image]\"; filename=\"b7jlq5pf52m11.png\"\r\nContent-Type: image/png\r\n"&gt;, "body"=&gt;"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris eget volutpat lectus. Donec neque urna, mattis ut fermentum non, iaculis sed est. Vestibulum odio tortor, scelerisque id maximus id, dignissim at turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent in magna vitae enim condimentum sollicitudin. Proin lobortis euismod velit. Aenean ac nibh a augue tempus dapibus eu sollicitudin leo. Fusce lorem arcu, tempor a ligula vitae, tincidunt finibus augue. Maecenas tempor odio sit amet molestie congue. Vestibulum porttitor neque dui, sit amet pharetra elit feugiat sit amet.", "technologies_attributes"=&gt;{"0"=&gt;{"name"=&gt;"Technology 0", "id"=&gt;"1"}, "1"=&gt;{"name"=&gt;"Technology 1", "id"=&gt;"2"}, "2"=&gt;{"name"=&gt;"Technology 2", "id"=&gt;"3"}, "3"=&gt;{"name"=&gt;"Technology 123", "id"=&gt;"4"}, "4"=&gt;{"name"=&gt;"Technology 1", "id"=&gt;"5"}, "5"=&gt;{"name"=&gt;"Technology 2", "id"=&gt;"6"}, "6"=&gt;{"name"=&gt;"Technology 0", "id"=&gt;"7"}, "7"=&gt;{"name"=&gt;"Technology 1", "id"=&gt;"8"}, "8"=&gt;{"name"=&gt;"Technology 2", "id"=&gt;"9"}, "9"=&gt;{"name"=&gt;"Technology 123", "id"=&gt;"10"}, "10"=&gt;{"name"=&gt;"Technology 1", "id"=&gt;"11"}, "11"=&gt;{"name"=&gt;"Technology 2", "id"=&gt;"12"}}}, "commit"=&gt;"Save Portfolio Item", "id"=&gt;"10"}
    Portfolio Load (1.5ms)  SELECT  "portfolios".* FROM "portfolios" WHERE "portfolios"."id" = $1 LIMIT $2  [["id", 10], ["LIMIT", 1]]
    ↳ app/controllers/portfolios_controller.rb:68
    User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
    ↳ app/controllers/concerns/current_user_concern.rb:5
     (0.2ms)  BEGIN
    ↳ app/controllers/portfolios_controller.rb:49
    Technology Load (1.1ms)  SELECT "technologies".* FROM "technologies" WHERE "technologies"."portfolio_id" = $1 AND "technologies"."id" IN ($2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)  [["portfolio_id", 10], ["id", 1], ["id", 2], ["id", 3], ["id", 4], ["id", 5], ["id", 6], ["id", 7], ["id", 8], ["id", 9], ["id", 10], ["id", 11], ["id", 12]]
    ↳ app/controllers/portfolios_controller.rb:49
    Portfolio Update (0.7ms)  UPDATE "portfolios" SET "main_image" = $1, "thumb_image" = $2, "updated_at" = $3 WHERE "portfolios"."id" = $4  [["main_image", "b7jlq5pf52m11.png"], ["thumb_image", "b7jlq5pf52m11.png"], ["updated_at", "2019-02-13 20:42:36.732254"], ["id", 10]]
    ↳ app/controllers/portfolios_controller.rb:49
     (0.4ms)  ROLLBACK
    ↳ app/controllers/portfolios_controller.rb:49
  Completed 500 Internal Server Error in 391ms (ActiveRecord: 18.3ms)
  
  
  
  Aws::S3::Errors::AccessDenied (Access Denied):
  
  app/controllers/portfolios_controller.rb:49:in `block in update'
  app/controllers/portfolios_controller.rb:48:in `update'
  </code></pre>
  
  <p>I expected this to work and be able to access the AWS resource but maybe there is some configuration I need to set for my bucket? The AWS documentation has been difficult to digest so far. I could use the help please and thank you. </p>