Opened 11 hours ago
Last modified 11 hours ago
#65230 new defect (bug)
`redirect_canonical()` fails to redirect slug-based attachment URLs when `wp_attachment_pages_enabled` is disabled
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 6.4 |
| Component: | Media | Keywords: | has-patch has-unit-tests |
| Focuses: | Cc: |
Description
When attachment pages are disabled (wp_attachment_pages_enabled = 0) and pretty permalinks are in use, visiting an attachment via its slug URL (e.g. /my-image-jpg/) returns a 200 with the attachment page rendered, instead of redirecting to the file. The query-string form (?attachment_id=123) for the same attachment correctly redirects.
This is a follow-up to #59866, which addressed the logged-in/anonymous discrepancy but did not cover the slug-URL code path.
Steps to reproduce
- Enable pretty permalinks (e.g.
/%postname%/). - Set
wp_attachment_pages_enabledto0. - Upload any media file.
- Visit the attachment's pretty permalink, e.g.
/my-image-jpg/.
Expected: 301 redirect to the file URL (e.g. /wp-content/uploads/2026/05/my-image.jpg).
Actual: 200 response with an attachment page rendered.
Cause
In src/wp-includes/canonical.php (~line 553), inside the is_attachment() && ! get_option( 'wp_attachment_pages_enabled' ) block:
$attachment_id = get_query_var( 'attachment_id' );
$attachment_post = get_post( $attachment_id );
get_query_var( 'attachment_id' ) is only populated for ?attachment_id=ID URLs. For slug-based URLs the query var is empty, so get_post( '' ) returns null, $attachment_url is falsy, and the redirect branch silently falls through.
Prior tickets
- #59866 — Attachment pages are only disabled for users that are logged in (fixed in 6.4.3; this ticket covers the slug-URL gap missed there)
- #57913 — Attachment pages need to have an "on" toggle (introduced the option)
Note: AI was used in the preparation of this ticket.
Change History (2)
This ticket was mentioned in PR #11816 on WordPress/wordpress-develop by @dd32.
11 hours ago
#2
- Keywords has-patch has-unit-tests added
When
wp_attachment_pages_enabledis0and pretty permalinks are active, accessing an attachment via its slug URL (e.g./my-image-jpg/) currently returns a 200 with an attachment page rendered, instead of redirecting to the underlying file. The query-string variant (?attachment_id=123) for the same attachment correctly redirects.The cause is in
redirect_canonical()(src/wp-includes/canonical.phparound line 553): the code retrieves the attachment ID viaget_query_var( attachment_id ), which is only populated for?attachment_id=NURLs. For slug-based attachment URLs the query var is empty, soget_post()receives an empty value, returnsnull, and the redirect is silently skipped.This change falls back to
get_queried_object_id()when theattachment_idquery var is empty, so the attachment ID resolves correctly for both URL forms. Tests are added intests/phpunit/tests/canonical/attachmentRedirect.phpcovering the slug and query-var URL forms, attachments on private/draft parents (the privacy guard at canonical.php ~line 800), and the no-redirect case when attachment pages remain enabled.