Image links failing

I am stumped, I have the following situation. I’ve got a page and an image image2.png in the same grav folder:


The page has in the markdown an image link:


nginx/grav serves up the page at URL

but the image doesn’t load in the browser, and in the HTML source, the image tag is rendered by Grav to be:

<img alt="connect" src="/user/pages/06.onboarding/03.test/image2.png" />

This is an invalid path according to the web server apparently. If I manually put in the browser the path to

then it shows the image. I also tested and found this strange behavior:


in the page’s markdown resolves to this HTML in the served up web page in the browser:

<a href=""></a>

Any help appreciated. I’ve got some rewrite going on or something, and I don’t know what’s doing it. I’ve looked over everything including nginx config file and I don’t see what might be out of place. Thx.

Grav should automatically support routing of media types and serve the image correctly. By default it uses the media types available in the media.yaml file. However if you have set some values in media.allowed_fallback_types in system. yaml, it will use that as a whitelist of valid types.

Have you removed the standard image types from media.yaml or set anything in that allowed_fallback_types?

BTW, quick fix is to call use ![](image2.png?cache) to force Grav to process/cache the image. Not the solution, but a quick workaround.

@rhukster: thanks for the replies. So the ?cache worked.

My user/config/media.yaml file is empty, I just deleted it. In system.yaml it has allowed_fallback_types: { }.

Still no image using ![](image2png).

fyi, I just downloaded a new instance of grav using the git install steps, and a test page there works for displaying the image. I would switch my /pages over to that location, but I’m having a cannot connect to gpm issue there. It’s on the same box, same web server, everything. I’ve tried the tips on this issue and still not resolved. So I’m back to getting my existing grav instance loading the images.

if you deleted your user/config/media.yaml it should use the system/config/media.yaml file which has a bunch of standard stuff including image files. Just works in my testing. You might need to send me a zip of your site.

How can I send you my site zip file?

@rhukster How about this, zip file is here:

update: I installed a completely new Grav base system and the "Grav is Running!’ default page with a linked image loaded fine, no problem with image displaying. Then I dropped my site’s /user folder in there, and the image loading issue persists. So not sure if it helps, but it narrows it down to a problem within my /user area.

@rhukster - were you able to get my zip file? Thx.

Well, it works fine for me. You forgot to include you htaccess, so I put the default one and your image is displayed. Did you change something on your .htaccess?

@paulmassendari, well that’s very interesting. Thank you for testing. Here is my .htaccess. I don’t know what it should be.

<IfModule mod_rewrite.c>

RewriteEngine On

## Begin RewriteBase
# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry
# You should change the '/' to your appropriate subfolder. For example if you have
# your Grav install at the root of your site '/' should work, else it might be something
# along the lines of: RewriteBase /<your_sub_folder>

# RewriteBase /

## End - RewriteBase

## Begin - Exploits
# If you experience problems on your site block out the operations listed below 
# This attempts to block the most common type of exploit `attempts` to Grav
# Block out any script trying to base64_encode data within the URL.
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Block out any script that includes a <script> tag in URL.
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL.
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL.
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Return 403 Forbidden header and show the content of the root homepage
RewriteRule .* index.php [F]
## End - Exploits

## Begin - Index
# If the requested path and file is not /index.php and the request
# has not already been internally rewritten to the index.php script
RewriteCond %{REQUEST_URI} !^/index\.php
# and the requested path and file doesn't directly match a physical file
RewriteCond %{REQUEST_FILENAME} !-f
# and the requested path and file doesn't directly match a physical folder
RewriteCond %{REQUEST_FILENAME} !-d
# internally rewrite the request to the index.php script
RewriteRule .* index.php [L]
## End - Index

## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat )$ error [F]
# Block access to specific file types for these user folders
RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block all direct access to .md files:
RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^|/)\.(?!well-known) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
## End - Security


# Begin - Prevent Browsing and Set Default Resources
Options -Indexes
DirectoryIndex index.php index.html index.htm
# End - Prevent Browsing and Set Default Resources

I’ve copied my nginx config file and .htaccess from other working sites into this one, cleared the cache and still the image doesn’t load. It still renders html as and it can’t load.

I’m at a loss!

well, that’s weird, as your htaccess seems untouched
. Locally, I have the following url which is working:

<img src="/learn/user/pages/06.onboarding/03.test/image2.png">

Browsing to


works too.

At first, I thought it might have been because of the numeric prefix on your subfolder, so before running apache locally, the only thing that I did after unzipping your zip is to rename your subfolder inside 06.onboarding without the folder prefix. I found that it worked, so I renamed your folder back to their initial name and it still worked.

Here is exactly what I did, just in case…
Does the problem only happen with this particular image?

I just tested your zip and after adding the default .htaccess, that page and URL worked for me.

Let me explain about the path tho. The /onboarding/test route works because Grav is routing that URL to to display the appropriate page. Also the /onboard/test/image2.png works because again Grav is falling-back after the request doesn’t find a specific page, and streaming the image2.png it did find in the route to your browser.

The actual physical path to the image is user/pages/06.onboarding/03.test/image2.png and this is what is output by default. This means the webserver serves this image directly (no going through Grav and therefore much faster and more efficient). This should definitely work for you as it works for me, works on learn, and basically works for all Grav sites. The fact that it doesn’t work means that your webserver is explicitly not routing it.

The strange thing is when i inspect your URL: and inspect the request/response, i see that Grav is actually responding with an H TML page not found (hence the broken image). That is weird, because the webserver should be serving up the physical file in user/pages/06.onboarding/03.test/image2.png and this ‘route’ is not a valid Grav route. So, definitely something weird with your server setup. Perhaps its related to symlinks or something else strange with your server filesystem?

Great info - thanks so much. I will try to remove symlinks to a Dropbox folder, bring it all within the grav folders without using symlinks and see what happens.

Amazing!! It loaded the image now. It must have been a symlink thing.

One final question - I also tested an external image link and it doesn’t show the image, on the web page it just shows the URL hyperlinked to the image.

In the markdown page, it is added as


You can see this on the bottom of

Will investigate this…

Just tested and it works for me with this url:


And doesn’t for me…I put in the exact same URL as you. I will investigate if there’s a conflict/issue with the mediaembed plugin.