← All writing

A file exists but the image returns 403: check permissions before changing URLs

Laravel / Apache shared hostingSources checked 2026-09-14

A blog image is present on disk, its URL is correct, and the browser still shows only alt text. A 403 response points to access being denied, which is different from a missing-file 404. Start with the response rather than rewriting the template blindly.

Trace the public file

curl -I https://example.com/uploads/writing/example.png
ls -l public/uploads/writing/example.png

Use your own public asset URL. Inspect the document root, symlink target, parent-directory access, and file mode. On a conventional shared host, public static files commonly need readable permissions such as 0644 and traversable directories such as 0755. Confirm the host's ownership and access model rather than applying recursive permission changes across the whole application.

Fix the narrow cause

A screenshot copied from a desktop can retain owner-only 0600 permissions. The account owner can read it over SSH while the static web server cannot. Correct that public file and its upload/deployment process. Never use 0777 as a general repair or make private backups public.

After the change, confirm a 200 response with the expected image content type and then load the image in the actual article. Lazy loading means an offscreen image may not be downloaded until you scroll near it.

If the response remains forbidden, inspect relevant server rules and logs. A hotlink rule, security module, or parent directory restriction can produce the same status. Existence alone is not proof of public delivery.

Reference

Official documentation.