Firefox experiences some noticeable delay before showing file-not-found page content, due to setTimeout in retryErrorCode
Categories
(Firefox :: Security, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr140 | --- | unaffected |
| firefox149 | --- | wontfix |
| firefox150 | --- | wontfix |
| firefox151 | --- | fixed |
People
(Reporter: dholbert, Assigned: jbrown)
References
(Blocks 1 open bug, Regression)
Details
(Keywords: perf, regression)
Attachments
(2 files)
STR:
- Visit
file://URI for a filename that does not exist, e.g.file:///tmp/bogus-file.html - (optional) Reload the page.
ACTUAL RESULTS:
There's a notable delay (feels like 1/2 second or so) where the content area is just blank, before the actual "File not found" UI shows up.
EXPECTED RESULTS:
No such delay.
Regression range:
https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=ffeda2cc60998e963e7d0cbbaf025926680129f0&tochange=9f7ec0c93a48daec7f488903dd24d2a9e4fea4f3
--> Regression from bug 2003587.
| Reporter | ||
Comment 1•15 days ago
|
||
Comment 2•15 days ago
|
||
Set release status flags based on info from the regressing bug 2003587
:jbrown, since you are the author of the regressor, bug 2003587, could you take a look? Also, could you set the severity field?
For more information, please visit BugBot documentation.
| Reporter | ||
Comment 3•15 days ago
|
||
Here's a profile taken in the first-bad Nightly (2026-01-01), where I'm just reloading a bogus file:// URL several times:
https://share.firefox.dev/3NVxFwT
As shown in the profile:
- The page is blank for ~380ms during each reload operation.
- and we're idle for most of that time, so it's not clear if anything useful is happening?
Looking a bit closer, there's a somewhat-long setTimeout involved -- the file:// content-process shows "setTimeout callback" about 100ms into the idle period. That looks to be for this function:
async function retryErrorCode() {
return new Promise(res => {
setTimeout(() => {
res(getErrorCode());
}, 100);
...which was indeed added in the regressor commit, here:
https://hg-edge.mozilla.org/integration/autoland/rev/9f7ec0c93a48daec7f488903dd24d2a9e4fea4f3#l19.29
I suspect that 100ms delay is responsible for most-if-not-all of the issue here.
Jack, could you take a look? Is there a reason we've got that 100ms delay there, and is it expected to be something that gets exercised for simple scenarios like loading a file-not-found page?
| Reporter | ||
Comment 4•15 days ago
|
||
(as a shot in the dark... maybe there's no network error-code associated with this file-not-found page, and so that's needlessly making us hit this retryErrorCode fallback code-path?)
| Reporter | ||
Comment 5•15 days ago
•
|
||
Yup, that's exactly it. Using regular devtools (no browser toolbox needed), I was able to step through this in the DevTools debugger.
- In chrome://global/content/aboutNetError.mjs , we hit
init()which callsgetErrorCode()like so:
https://searchfox.org/firefox-main/rev/0ea834f7eeb962c70f3232e782830290e63c0951/toolkit/content/aboutNetError.mjs#1324-1330
async function init() {
let errorCode = await getErrorCode();
let i = 0;
while (!errorCode && i < 3) {
i++;
errorCode = await retryErrorCode();
}
-
Inside
getErrorCode(), we see thatgIsCertErrorisfalseso we returndocument.getNetErrorInfo().errorCodeString-- which for this page is an empty string (i.e."") -
So: back up in
init, our!errorCodetruthiness-check fails (the empty string evaluates to false), and we callretryErrorCode(), which is doomed to get the same empty-string response (I assume) three times in a row. So we eat up 300ms (3 loops with a100mssetTimeout in each) for no good reason, before we get around to painting the page.
| Reporter | ||
Comment 6•15 days ago
•
|
||
Note for testing & regression-tracking purposes: the regressor here happened to include a pref-flip (toggling security.certerrors.felt-privacy-v1 to true), but this bug reproduces regardless of whether that about:config pref is true or false. This bug was introduced by other logic that was in the regressing commit, and that logic runs regardless of the pref's true/false value.
So: this was a new regression in 148 and affects all releases since then, independent from pref values (and I confirmed that it affects current release v149 with a fresh Firefox profile).
| Reporter | ||
Updated•15 days ago
|
Updated•14 days ago
|
| Assignee | ||
Comment 7•6 days ago
|
||
Updated•6 days ago
|
| Assignee | ||
Comment 8•6 days ago
|
||
Hey Daniel, I remember I had to add the retry logic in D275665 because we need to give IPC enough time to deliver the cert security info for subframe cert errors. I mentioned this in a comment in that patch:
When a subframe hits a cert error, the error page would load and run NetErrorCard.isSupported() immediately, and sometimes the parent process hadn't finished sending the failed-channel security info yet via IPC by that time.
Then we'd end up with an undefined errorCodeString, isSupported would return false, and the legacy page would render instead of net-error-card.
On the other hand, we only need this for cert errors, and the file:// not-found pages you mentioned are not cert errors.
We should be able to gate the retry loop on gIsCertError. I added a patch with this change.
Updated•4 days ago
|
Comment 10•4 days ago
|
||
| bugherder | ||
Updated•3 days ago
|
Comment 11•1 day ago
|
||
The patch landed in nightly and beta is affected.
:jbrown, is this bug important enough to require an uplift?
- If yes, please nominate the patch for beta approval.
- See https://wiki.mozilla.org/Release_Management/Requesting_an_Uplift for documentation on how to request an uplift.
- If no, please set
status-firefox150towontfix.
For more information, please visit BugBot documentation.
| Assignee | ||
Updated•3 hours ago
|
Description
•