Image Editor reload appends stacking cache timestamp and doesn't reflect edits behind a CDN
@i-just is already working on this.
Since Jun 15, 2026.
Assessment
This issue has not been assessed yet.
Description
Description
When you edit an image with the asset Image Editor from inside a CKEditor field, _reloadImage() in src/web/assets/ckeditor/src/image/imageeditor/imageeditorcommand.js builds a cache-busted src from srcInfo.baseSrc. But baseSrc comes from the greedy (.*) in _srcInfo()'s regex:
const match = src.match(/(.)#asset:(\d+)(?::transform:([a-zA-Z][a-zA-Z0-9_]))?/);
// baseSrc = match[1] → everything before "#asset:", INCLUDING any existing query
So baseSrc already contains the previously-appended ?, and _reloadImage() appends another one each time:
let newSrc = image.srcInfo.baseSrc + '?' + new Date().getTime() + '#asset:' + image.srcInfo.assetId;
The query string stacks on every edit, producing malformed URLs (a URL can only have one ?):
…/MT-3_2026-06-09-020259_hbsn.jpeg?0?1780971727673?1780971779690?1780971926837#asset:1395663
This stacked URL is then persisted into the stored field content.
A second, related problem: even with a single valid cache-buster, the editor swaps the src immediately on save with no allowance for CDN propagation. When assets are served through a CDN that caches by path / doesn't vary on the query string and invalidates asynchronously (e.g. CloudFront + AWS Serverless Image Handler, which is a very common Craft setup), the reload fetches the still-cached pre-edit image, so the edit doesn't visibly update — often requiring repeated saves or a hard refresh.
For reference, Craft core avoids this for its own thumbnails by deriving a stable, content-based buster from the asset's modified time (AssetsHelper::revUrl() / revParams() → ?v=), rather than appending a fresh timestamp onto whatever is already in the src.
imageeditorcommand.js
Steps to reproduce
- Insert an image asset into a CKEditor field and save the entry.
- Select the image → open the Image Editor → crop/rotate → Save.
- Repeat step 2 two or three more times.
- View the image src (editor "Source" view or the saved field content): the query string accumulates — ???… — instead of being replaced.
- (If assets are behind a CDN like CloudFront/Serverless Image Handler) the edited image also fails to display the change until multiple saves / a hard refresh, because the stale CDN copy keeps being served.
Additional info
Craft version: 5.10.5
PHP version: 8.2.28
Database driver & version: MySQL 8.0.40
Plugins & versions:
CKEditor (craftcms/ckeditor), 5.x branch (CKEditor 5, ckeditor5 ^48.2.0)
AWS S3 (craftcms/aws-s3) 2.3.0 — assets on S3 served via CloudFront + Serverless Image Handler
- Dominant language
- PHP
- Stars
- 47
- Forks
- 32
- Avg merge
- 3d 20h
- Merged PRs (30d)
- 3
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from craftcms/ckeditor
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
[5.x]: InvalidSubpathException when Default Upload Location uses an object template like {slug}Possibly taken @i-just claimed this 6 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 55/100
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 25/100
All issues in craftcms/ckeditor
Similar issues
-
sync-en
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
bug Feature: Kiosk
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Infrastructure: actions Module: zmscitizenapi Module: zmsentities php Type: Bug unit tests
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
it-at-m/eappointment#3480 ·
Maintainers usually reply within 1 day
-
HttpClient
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
CI: composer install fails — league/flysystem 1.x blocked by security advisory GHSA-cxf4-7mrp-vvprOpendevops type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day