Answers.Body: <p>It appears nginx is setup correctly. In Craft, your Assets URL can be different than your assets path, which I think is where some confusion is coming in.</p>
  
  <p>If Craft's file upload path is outside nginx <code>root</code> (otherwise known as the <code>DocumentRoot</code> directive in Apache), you could either move your asset storage so it's <em>under</em> the document root—and thus "public" or "virtually move" the <code>root</code> folder so nginx will serve from that directory instead of the actual "images" folder.</p>
  
  <pre><code>location /images/ {
    /root /srv/craft/uploads
  }
  </code></pre>
  
  <p>As with great power comes great responsibility. If you use the virtual rewriting option, be careful to always specify a default document root, and only override the root inside a location unless you have to <a href="https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#root-inside-location-block" rel="nofollow">as noted in nginx docs</a>, or nothing will match and you'll pull your hair out as to why nothing matches.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-01-15T13:08:01.427Z
Answers.Text: OK I've updated my Nginx configuration with the advice you have provided, and it works. Thanks again.
Answers.UserDisplayName: sctgraham
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-01-14T23:42:59.710Z
Answers.LastActivityDate: 2016-01-14T23:42:59.710Z
Answers.UserDisplayName: RitterKnight
Answers.Body: <p>Just had a similar issue with a colleague. <strong>Double check your folder permissions</strong>. It might be the case that Craft isn’t allowed to write the transformed files to your assets folder.</p>
  
  <p>Something like <code>chmod -R 777 public/assets</code> might do the trick. </p>
  
  <p>(You might want set this to something other than <code>777</code> if it worked out. Look at <a href="https://craftcms.com/docs/installing#step-2-set-the-permissions" rel="nofollow noreferrer">the docs</a> for details.)</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-06T23:19:49.473Z
Answers.Text: Thank you for this! I needed to change my upload directory to use 777 permissions to get things working.
Answers.UserDisplayName: Anna_MediaGirl
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-18T14:52:19.180Z
Answers.LastActivityDate: 2017-07-18T14:52:19.180Z
Answers.UserDisplayName: medoingthings
Answers.Body: <p>Not a direct answer to your question, but I keep a pretty up to date Nginx config for Craft here: <a href="https://github.com/nystudio107/nginx-craft" rel="nofollow noreferrer">Nginx-Craft</a> that may be useful to you at some point.</p>
  
  <p>Glad you got it sorted.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-18T16:12:36.657Z
Answers.LastActivityDate: 2017-07-18T16:12:36.657Z
Answers.UserDisplayName: andrew.welch
Answers.Body: <p>I replaced some of my Nginx configuration with the ones from here:</p>
  <p>[https://github.com/nystudio107/nginx-craft/blob/master/sites-available/basic_localdev.com.conf][1]</p>
  <p>I believe this line is what resolved it for me</p>
  <p>location / {
  try_files $uri/index.html $uri $uri/ /index.php?$query_string;
  }</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-03-26T12:47:54.350Z
Answers.LastActivityDate: 2021-03-26T12:47:54.350Z
Answers.UserDisplayName: Victor Ighalo
Body: <p>I have the following issue which I can't seem to wrap my head around. </p>
  
  <p>All images assets uploaded to Craft return a 404 not found on the front-end. Everything works fine in the admin CP though (uploading, renaming, thumbnails, etc.). Any template with <code>getUrl()</code> outputs the correct URL but the resource returns a 404 status code. When I navigate directly to the asset's URL, Craft returns a 404 template instead of the image. </p>
  
  <p>These are the things I have checked so far :</p>
  
  <ul>
  <li>Files permissions seem OK (775 on folder and 664 on files) on the "craft" user;</li>
  <li>The assets paths is <code>{basePath}uploads/images/</code></li>
  <li>The assets URL is <code>{siteUrl}images/</code></li>
  <li>Both <code>{basePath}</code> and <code>{siteUrl}</code> are correctly set as environment variables in <code>general.php</code></li>
  <li>I'm running Nginx with a config similar to <a href="https://craftcms.stackexchange.com/a/8971">this answer</a></li>
  </ul>
  
  <p>Any thoughts ? This is really bugging me.</p>
  
  <p>Thanks.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>These are my two nginx configuration files :</p>
  
  <pre><code># nginx.conf
  
  user craft craft;
  worker_processes auto;
  worker_rlimit_nofile 8192;
  events {
      worker_connections 8000;
  }
  
  error_log /var/log/nginx/error.log debug; # not for production
  pid /var/run/nginx.pid;
  
  
  http {
  
      disable_symlinks off;
      proxy_buffering on;
      proxy_buffer_size 8k;
      proxy_buffers 2048 8k;
      proxy_connect_timeout  600s;
      proxy_send_timeout  600s;
      proxy_read_timeout  600s;
      fastcgi_send_timeout 600s;
      fastcgi_read_timeout 600s;
  
      rewrite_log on;
      access_log /var/log/nginx/access.log;
  
      server_tokens off;
      include /etc/nginx/mime.types;
      default_type application/octet-stream;
      keepalive_timeout   65;
      sendfile            on;
      tcp_nopush          on;
      gzip                on;
      gzip_comp_level     5;
      gzip_min_length     256;
      gzip_proxied        any;
      gzip_vary           on;
      gzip_disable        "msie6";
  
      include /etc/nginx/sites-enabled/*;
  }
  </code></pre>
  
  <p>and </p>
  
  <pre><code># site.conf
  
  # -------------------------------------------------
  # General server configuration
  
  server {
  
    listen 80 default_server;
    server_name example.com;
    root /srv/craft/public;
    index index.php index.html index.htm;
    charset utf-8;
    error_page 404 /index.php;
    error_log /var/log/nginx/example.com.error.log debug;
    access_log /var/log/nginx/example.com.access.log;
  
    # -------------------------------------------------
    # Some locations to help during dev, remove for production
  
    location = /phpinfo {
      try_files $uri $uri/ /phpinfo.php$is_args$args;
    }
  
    location = /status {
       access_log off;
       allow all;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME /status;
       fastcgi_pass unix:/var/run/php-fpm.sock;
    }
  
    location = /ping {
       access_log off;
       allow all;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME /ping;
       fastcgi_pass unix:/var/run/php-fpm.sock;
    }
  
    # -------------------------------------------------
    # Static assets (css, js, fonts, etc.) location
  
    location /src {
        root /srv/craft/public/src;
        expires 1y;
        access_log off;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # -------------------------------------------------
    # Craft application locations
  
    location / {
      try_files $uri $uri/ @rewrites;
    }
  
    location @rewrites {
      rewrite ^(.*) /index.php?p=$1 last;
    }
  
    location ~ \.php$ {
      try_files $uri =404;
      include fastcgi_params;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/var/run/php-fpm.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
  
    # cache.appcache, your document html and data
    location ~* \.(?:manifest|appcache|html?|xml|json)$ {
        try_files $uri /index.php?$query_string;
        expires -1;
    }
  
    # Feed
    location ~* \.(?:rss|atom)$ {
        try_files $uri /index.php?$query_string;
        expires 1h;
        add_header Cache-Control "public";
    }
  
    # Media: images, icons, video, audio, HTC
    location ~* \.(?:jpg|jpeg|gif|png|pdf|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
        try_files $uri /index.php?$query_string;
        expires 1M;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # CSS and Javascript
    location ~* \.(?:css|js)$ {
        try_files $uri /index.php?$query_string;
        expires 1y;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # -------------------------------------------------
    # Other static ressources
  
    # Favicons
    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }
  
    # Robots.txt
    location = /robots.txt {
        access_log off;
        log_not_found off;
    }
  
    # Humans.txt
    location = /humans.txt {
        access_log off;
        log_not_found off;
    }
  
    # Prevent clients from accessing hidden files (starting with a dot)
    # This is particularly important if you store .htpasswd files in the site hierarchy
    location ~* (?:^|/)\. {
        deny all;
    }
    # Prevent clients from accessing to backup/config/source files
    location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
        deny all;
    }
  
  }
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T18:10:10.620Z
Comments.Text: Can you post your nginx config?  It sounds like one of the rules dealing with static files isn't being followed. That could be for number of reasons. As a general rule, when processing a config, nginx looks for more exact rules first and then down to less and less specific.
Comments.UserDisplayName: RitterKnight
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T19:00:53.103Z
Comments.Text: Shouldn't the assets URL be `{siteUrl}uploads/images`?
Comments.UserDisplayName: megatrond
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T21:38:55.090Z
Comments.Text: @RitterKnight I've added the Nginx files, you'll see a /src location which is working fine to serve static ressources (JS, CSS, fonts and UI images) not managed by craft. Maybe something is wrong with the media location further down the file.
Comments.UserDisplayName: sctgraham
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T21:43:06.590Z
Comments.Text: @megatrond No, I want the images to be served from example.com/images/ but I don't think the folder path should necessarily match that url fragment for this to work. At least I hope not !
Comments.UserDisplayName: sctgraham
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T21:56:19.087Z
Comments.Text: It appears like nginx is setup correctly what what I can tell. I would double check your asset source's location.  Where are the images that craft maintains stored? I would guess under /images/? Those have to be some folder under /public as well unless you have a nginx rule that rewrites them.
Comments.UserDisplayName: RitterKnight
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T22:15:14.430Z
Comments.Text: Just rereading your question, your Assets URL should match your assets path. If i'm reading your config right, BasePath would be ``/srv/craft/public``.  I would guess your URLs are coming out like ``whatever.com/images/`` when they should be coming out like ``whatever.com/uploads/images``.
Comments.UserDisplayName: RitterKnight
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T22:16:30.653Z
Comments.Text: @RitterKnight you are right, my folder location is outside the Nginx root path. It's actually under /srv/craft/uploads/ and not /srv/craft/public. I wanted to keep those files separate for version control reasons. So that's more than likely the issue, I'm off to test this now. However, one quick question  : would the solution be as simple as adding "root /srv/craft/uploads/" to the media location or will this potentially interfere with any other Craft media files ? Thanks a mil for you time and help.
Comments.UserDisplayName: sctgraham
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-01-14T22:33:28.580Z
Comments.Text: Craft's static assets from the CP get served by PHP so you should be good there. Yeh if you make  new ``location /images`` block, the root you mention would serve it out of that directory and nginx would use files in that location when it encounters something from ``whatever.com/images/``.
Comments.UserDisplayName: RitterKnight
Tags: <assets><image><404><debugging>
Title: Assets (images) return a 404 on the front-end
ThreadText: # Assets (images) return a 404 on the front-end
  
  (Asked by: username_0 on 2016-01-14)
  
  I have the following issue which I can't seem to wrap my head around.
  
  All images assets uploaded to Craft return a 404 not found on the front-end. Everything works fine in the admin CP though (uploading, renaming, thumbnails, etc.). Any template with `getUrl()` outputs the correct URL but the resource returns a 404 status code. When I navigate directly to the asset's URL, Craft returns a 404 template instead of the image.
  
  These are the things I have checked so far :
  
  * Files permissions seem OK (775 on folder and 664 on files) on the "craft" user;
  * The assets paths is `{basePath}uploads/images/`
  * The assets URL is `{siteUrl}images/`
  * Both `{basePath}` and `{siteUrl}` are correctly set as environment variables in `general.php`
  * I'm running Nginx with a config similar to [this answer](https://craftcms.stackexchange.com/a/8971)
  
  Any thoughts ? This is really bugging me.
  
  Thanks.
  
  **Edit**
  
  These are my two nginx configuration files :
  
  ```
  # nginx.conf
  
  user craft craft;
  worker_processes auto;
  worker_rlimit_nofile 8192;
  events {
      worker_connections 8000;
  }
  
  error_log /var/log/nginx/error.log debug; # not for production
  pid /var/run/nginx.pid;
  
  http {
  
      disable_symlinks off;
      proxy_buffering on;
      proxy_buffer_size 8k;
      proxy_buffers 2048 8k;
      proxy_connect_timeout  600s;
      proxy_send_timeout  600s;
      proxy_read_timeout  600s;
      fastcgi_send_timeout 600s;
      fastcgi_read_timeout 600s;
  
      rewrite_log on;
      access_log /var/log/nginx/access.log;
  
      server_tokens off;
      include /etc/nginx/mime.types;
      default_type application/octet-stream;
      keepalive_timeout   65;
      sendfile            on;
      tcp_nopush          on;
      gzip                on;
      gzip_comp_level     5;
      gzip_min_length     256;
      gzip_proxied        any;
      gzip_vary           on;
      gzip_disable        "msie6";
  
      include /etc/nginx/sites-enabled/*;
  }
  
  ```
  
  and
  
  ```
  # site.conf
  
  # -------------------------------------------------
  # General server configuration
  
  server {
  
    listen 80 default_server;
    server_name example.com;
    root /srv/craft/public;
    index index.php index.html index.htm;
    charset utf-8;
    error_page 404 /index.php;
    error_log /var/log/nginx/example.com.error.log debug;
    access_log /var/log/nginx/example.com.access.log;
  
    # -------------------------------------------------
    # Some locations to help during dev, remove for production
  
    location = /phpinfo {
      try_files $uri $uri/ /phpinfo.php$is_args$args;
    }
  
    location = /status {
       access_log off;
       allow all;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME /status;
       fastcgi_pass unix:/var/run/php-fpm.sock;
    }
  
    location = /ping {
       access_log off;
       allow all;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME /ping;
       fastcgi_pass unix:/var/run/php-fpm.sock;
    }
  
    # -------------------------------------------------
    # Static assets (css, js, fonts, etc.) location
  
    location /src {
        root /srv/craft/public/src;
        expires 1y;
        access_log off;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # -------------------------------------------------
    # Craft application locations
  
    location / {
      try_files $uri $uri/ @rewrites;
    }
  
    location @rewrites {
      rewrite ^(.*) /index.php?p=$1 last;
    }
  
    location ~ \.php$ {
      try_files $uri =404;
      include fastcgi_params;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/var/run/php-fpm.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
  
    # cache.appcache, your document html and data
    location ~* \.(?:manifest|appcache|html?|xml|json)$ {
        try_files $uri /index.php?$query_string;
        expires -1;
    }
  
    # Feed
    location ~* \.(?:rss|atom)$ {
        try_files $uri /index.php?$query_string;
        expires 1h;
        add_header Cache-Control "public";
    }
  
    # Media: images, icons, video, audio, HTC
    location ~* \.(?:jpg|jpeg|gif|png|pdf|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
        try_files $uri /index.php?$query_string;
        expires 1M;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # CSS and Javascript
    location ~* \.(?:css|js)$ {
        try_files $uri /index.php?$query_string;
        expires 1y;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
  
    # -------------------------------------------------
    # Other static ressources
  
    # Favicons
    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }
  
    # Robots.txt
    location = /robots.txt {
        access_log off;
        log_not_found off;
    }
  
    # Humans.txt
    location = /humans.txt {
        access_log off;
        log_not_found off;
    }
  
    # Prevent clients from accessing hidden files (starting with a dot)
    # This is particularly important if you store .htpasswd files in the site hierarchy
    location ~* (?:^|/)\. {
        deny all;
    }
    # Prevent clients from accessing to backup/config/source files
    location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
        deny all;
    }
  
  }
  
  ```
  
  **Tags:** assets, image, 404, debugging
  
  > **Comments:**
  > **username_1**: Can you post your nginx config?  It sounds like one of the rules dealing with static files isn't being followed. That could be for number of reasons. As a general rule, when processing a config, nginx looks for more exact rules first and then down to less and less specific.  
  > **username_2**: Shouldn't the assets URL be `{siteUrl}uploads/images`?  
  > **username_0**: @username_1 I've added the Nginx files, you'll see a /src location which is working fine to serve static ressources (JS, CSS, fonts and UI images) not managed by craft. Maybe something is wrong with the media location further down the file.  
  > **username_0**: @username_2 No, I want the images to be served from example.com/images/ but I don't think the folder path should necessarily match that url fragment for this to work. At least I hope not !  
  > **username_1**: It appears like nginx is setup correctly what what I can tell. I would double check your asset source's location.  Where are the images that craft maintains stored? I would guess under /images/? Those have to be some folder under /public as well unless you have a nginx rule that rewrites them.  
  > **username_1**: Just rereading your question, your Assets URL should match your assets path. If i'm reading your config right, BasePath would be ``/srv/craft/public``.  I would guess your URLs are coming out like ``whatever.com/images/`` when they should be coming out like ``whatever.com/uploads/images``.  
  > **username_0**: @username_1 you are right, my folder location is outside the Nginx root path. It's actually under /srv/craft/uploads/ and not /srv/craft/public. I wanted to keep those files separate for version control reasons. So that's more than likely the issue, I'm off to test this now. However, one quick question  : would the solution be as simple as adding "root /srv/craft/uploads/" to the media location or will this potentially interfere with any other Craft media files ? Thanks a mil for you time and help.  
  > **username_1**: Craft's static assets from the CP get served by PHP so you should be good there. Yeh if you make  new ``location /images`` block, the root you mention would serve it out of that directory and nginx would use files in that location when it encounters something from ``whatever.com/images/``.  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_1 on 2016-01-14. Score: 1 | Accepted answer
  
  It appears nginx is setup correctly. In Craft, your Assets URL can be different than your assets path, which I think is where some confusion is coming in.
  
  If Craft's file upload path is outside nginx `root` (otherwise known as the `DocumentRoot` directive in Apache), you could either move your asset storage so it's *under* the document root—and thus "public" or "virtually move" the `root` folder so nginx will serve from that directory instead of the actual "images" folder.
  
  ```
  location /images/ {
    /root /srv/craft/uploads
  }
  
  ```
  
  As with great power comes great responsibility. If you use the virtual rewriting option, be careful to always specify a default document root, and only override the root inside a location unless you have to [as noted in nginx docs](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#root-inside-location-block), or nothing will match and you'll pull your hair out as to why nothing matches.
  
  > **Comments:**
  > **username_0**: OK I've updated my Nginx configuration with the advice you have provided, and it works. Thanks again.  
  
  ---
  
  ### Answer by username_3 on 2017-07-18. Score: 3
  
  Just had a similar issue with a colleague. **Double check your folder permissions**. It might be the case that Craft isn’t allowed to write the transformed files to your assets folder.
  
  Something like `chmod -R 777 public/assets` might do the trick.
  
  (You might want set this to something other than `777` if it worked out. Look at [the docs](https://craftcms.com/docs/installing#step-2-set-the-permissions) for details.)
  
  > **Comments:**
  > **username_4**: Thank you for this! I needed to change my upload directory to use 777 permissions to get things working.  
  
  ---
  
  ### Answer by username_5 on 2017-07-18. Score: 1
  
  Not a direct answer to your question, but I keep a pretty up to date Nginx config for Craft here: [Nginx-Craft](https://github.com/nystudio107/nginx-craft) that may be useful to you at some point.
  
  Glad you got it sorted.
  
  
  ---
  
  ### Answer by username_6 on 2021-03-26. Score: 0
  
  I replaced some of my Nginx configuration with the ones from here:
  
  [https://github.com/nystudio107/nginx-craft/blob/master/sites-available/basic\_localdev.com.conf][1]
  
  I believe this line is what resolved it for me
  
  location / {
  try\_files $uri/index.html $uri $uri/ /index.php?$query\_string;
  }
  
  
  ---
  
  