Release notes: 2.6
Last updated Edit this page View as Markdown
mod_pagespeed 2.6.0 release notes: security fixes for the nginx and Apache modules, and an optimizer service that can start after the web server.
mod_pagespeed 2.6.0 is the current release: the module and the optimizer worker, released together on 2026-10-28 and installed as a matching pair. The packages in the signed apt and yum repositories, the container images, the NuGet packages (including the ASP.NET Core sidecar packages) and the Helm chart’s application version all carry the product version. The release notes index lists every release of every line, and Security updates lists every security fix we have published with the release that carried it.
mod_pagespeed 2.6.0 2026-10-28 module + optimizer worker
Release date: 2026-10-28
Status: Stable
Packages: mod-pagespeed (Apache), nginx-module-pagespeed, the IIS
installer and the cPanel package, with the matching pagespeed-optimizer;
the container images, the NuGet packages including the ASP.NET Core sidecar
packages (WeAmp.PageSpeed.Sidecar,
WeAmp.PageSpeed.Sidecar.NativeAssets.Linux) and the Helm chart’s
application version carry the same version.
Highlights
-
Security: two fixes for the nginx module and two for the Apache module. Update recommended. See Security below.
-
The module picks up an optimizer service that starts after the web server, without a restart. IIS and Apache check again every 30 seconds and turn in-place optimization back on once the optimizer answers. nginx checks again at most once every 30 seconds, and only while requests arrive. On IIS, an optimizer service the module cannot use is now reported in the Windows event log, and a worker process crash that could occur while rewriting HTML under load is fixed.
-
More accurate caching headers. Rewritten HTML names in
Varythe request headers its markup depends on, an optimized response whose content identity is unknown no longer carries anETagthat could confirm a stale copy, and conditional requests to the optimizer cache follow HTTP more closely. Sites that let a CDN or shared cache store rewritten HTML should read Upgrade notes. -
nginx:
pagespeedsettings in alocationnow apply inside its nested locations andifblocks. If you relied on a nested block escaping the enclosing location’s settings, see Upgrade notes. -
Statistics and ETags no longer make an optimizer outage look healthy. Responses answered with the stored original are counted in a new
ipro_daemon_served_originalstatistic and carry the origin’s own ETag;ipro_daemon_servedcounts optimized responses only. If you monitoripro_daemon_served, see Upgrade notes. -
The
mobilizeandinsert_gafilters are now no-ops that log a warning. Existing configurations keep loading. See Deprecations. -
Building from source: Bazel 8 with bzlmod, and no Java. The build uses Bazel 8.8.1 with every dependency declared in
MODULE.bazel; the Closure Compiler is gone, so Java is no longer needed. The experimental Envoy filter builds again, against Envoy 1.40.1. Packages and images need no action.
Affected ranges use package version numbers. Module and optimizer host packages 1.16.0 to 1.19.0 shipped with product versions 2.1.0 to 2.4.0; 2.0.x versions were NuGet-only releases.
Security
- nginx: fixed a denial-of-service issue in the admin endpoints. Affected: 1.15.0 to 2.5.2. Update recommended.
- nginx: fixed a request-handling security issue. Affected: 1.5.27 to 2.5.2. Update recommended.
- Apache: fixed an issue that could expose origin data to browsers in some proxy configurations (security fix). Affected: 1.4.26 to 2.5.2. Update recommended.
- Apache: fixed a memory-safety issue that could be triggered in some configurations (security fix). Affected: 1.3.25 to 2.5.2. Update recommended.
Changed behaviour
-
IIS reports an optimizer service it cannot use in the Windows event log. When a worker process starts with a configured optimizer service it cannot use (the service stopped,
DaemonSocketPathorDaemonVolumePathmissing, a missing or outdated client library, a package fault), it serves normally with in-place optimization off and now writes one event-log warning per configuration, whateverUseEventLogsays. For a stopped service the entry says the module checks again every 30 seconds (an informational entry follows when the service is reattached); for the other causes it names both configured paths and says to correct the cause and recycle the application pool. Each entry names its own cause, and an unset path is shown as(not set). Local requests also carryX-Pagespeed-Init-Status: daemon-unavailable, and responses carrying it are never cached. Apache and nginx already logged this in their error log. -
nginx:
pagespeedsettings in alocationblock now also apply inside its nested locations and itsifandlimit_exceptblocks. Before, such a nested block ran with the server-level settings only, so pages excluded withpagespeed offon the location, or narrowed withpagespeed Allow,pagespeed Disallow, filter or caching settings, could still be optimized. A nested block that sets nopagespeeddirectives of its own now inherits the enclosing location’s settings, as other nginx modules’ directives do. See Upgrade notes. -
Rewritten HTML names the request headers that change it in
Vary. With image optimization on, the markup chosen for a page can differ by the browser’s image-format support (Accept), its data-saver preference (Save-Data) and its device (User-Agent). Pages rewritten with such optimizations now carryVarynaming exactly the headers the configured filters depend on; the value depends only on your configuration, not on the request or on cache state. With the default settings HTML is still served as not cacheable by shared caches, so most sites see no change. If you let a CDN or shared cache store rewritten HTML, this lets a cache that honours Vary keep each variant separate. Update recommended for those sites; see Upgrade notes. -
A client reload no longer bypasses the optimizer’s cached copy of a resource unless you ask for it. Before, a request with
Cache-Control: no-cacheorPragma: no-cachewas sent to the origin instead of being served from the optimizer’s cache, whileCache-Control: max-age=0never was. Now all of these are served from the cache by default. The new optionDaemonServeHonorRequestFreshness(per server or site, default off) turns the bypass back on for all three forms, in any letter case. Apache:ModPagespeedDaemonServeHonorRequestFreshness on; nginx:pagespeed DaemonServeHonorRequestFreshness on;; IIS:pagespeed DaemonServeHonorRequestFreshness on. Apache, nginx and IIS with the optimizer. -
New option
PublicAdminAccessfor an intentionally public admin console. Process scope, default off. When on, the module logs one informational line instead of the “intended for loopback” warning for admin handlers, and the console’s Overview shows “This console is public by configuration” instead of “Admin console reachable from the network”. Access control is unchanged. Apache:ModPagespeedPublicAdminAccess on; nginx:pagespeed PublicAdminAccess on;in the main context. -
Statistics for responses served from the optimizer’s stored original. With the optimizer service stopped, recorded URLs were answered with the stored original while
ipro_daemon_servedkept climbing and the response carried theW/"ps-ETag that marks optimized output.ipro_daemon_servednow counts optimized variants only; the newipro_daemon_served_originalcounts responses answered with the stored original, and those carry the origin’s own weak ETag. An origin that sent no ETag, or a malformed one, now yields a response with no ETag. Apache, nginx and IIS. -
prioritize_critical_imagessendsVary: Save-Dataconsistently. With Save-Data image qualities in effect, HTML handled by this filter now carriesVary: Save-Datawhenever the filter and critical-image reporting are enabled. Before, the header appeared only once browsers had reported critical images, so right after a cache purge a shared cache could key the page inconsistently. -
Messages say “optimizer” instead of “daemon”. Module log and error messages (split cache volume, volume open, socket reachability, in-place serve lines, admin proxy errors) and the admin console’s headings, alerts and help text now say “the optimizer” or “the optimizer worker”. Directives (
DaemonSocketPath,DaemonVolumePath, …), statistics, the/v1/daemon/*endpoints and their error codes are unchanged. If you match log lines by text, check your patterns. -
Package descriptions name the product mod_pagespeed.
apt showanddnf infodescribemod-pagespeedandnginx-module-pagespeedas the mod_pagespeed web page optimization module for Apache httpd and for nginx. -
The admin console no longer lists
inserted_ga_snippets. Onlyinsert_gacould increase it, and that filter is now a no-op. -
Building from source.
- The Bazel build uses Bazel 8.8.1 and is bzlmod only: every dependency is
declared in
MODULE.bazelwith a committedMODULE.bazel.lock. TheWORKSPACEfiles andscripts/use-envoy-workspace.share removed. - The Closure Compiler is no longer a build dependency; the client scripts are built with a pinned esbuild, so Java is not needed. The shipped scripts behave the same and keep their public names; the deferred-JavaScript script grew by about 8 KB uncompressed and 1 KB gzipped (from about 12 KB to about 20 KB uncompressed, and from about 4.2 KB to about 5.2 KB gzipped).
- The Envoy filter builds again, against Envoy 1.40.1:
bazel build --config=envoy-filter //pagespeed/envoy:envoy_pagespeed //pagespeed/envoy:pagespeed_filter.so. It remains experimental and ships in no package. pagespeed_libraries.confnow lives atinstall/common/pagespeed_libraries.confin the source tree (the oldnet/instaweb/genfiles/tree is removed). The installed file and its location are unchanged; update any script or link that fetched it from the repository.- The Debian and RPM package build scripts now stop with an error when
pagespeed_libraries.confis missing, instead of producing a package without it.
- The Bazel build uses Bazel 8.8.1 and is bzlmod only: every dependency is
declared in
Fixed
-
IIS and Apache pick up an optimizer service that starts or restarts after the web server, without a restart. A worker process that started while the service was not running kept in-place optimization off until the application pool was recycled or the server restarted. The module now checks again every 30 seconds and turns in-place optimization back on once the service answers, with one info line. A split cache volume and other configuration or package faults are still final until a restart. Affected: 1.16.0 to 2.5.2.
-
nginx picks up an optimizer that starts after nginx, without a reload. A worker process that started while the optimizer was not running kept in-place optimization off until nginx was reloaded or restarted. While requests arrive, each nginx worker process now checks for the optimizer again at most once every 30 seconds, off the request path, and turns in-place optimization back on once the optimizer answers, with one info line in the error log. A split cache volume and other configuration or package faults remain final until a restart. Affected: 1.17.0 to 2.5.2.
-
A web server process can no longer attach to a cache file that another process is discarding. When the module and the optimizer disagree on the cache layout (for example during an upgrade), a second process starting at the same moment could attach to the file being discarded and run without in-place optimization until it restarted. Opens of the optimizer’s cache are now coordinated between the web server’s processes. On Windows a small hidden lock file (
.pagespeed-module-open.lock) appears in the optimizer’s cache directory; it is expected and can be left in place. Affected: 1.16.0 to 2.5.2. -
A changed optimized resource is no longer answered
304 Not Modifiedwhen its origin sends neitherETagnorLast-Modified. Its validator was derived from the response length alone, so a new version of the same optimized length could be confirmed as unchanged and the browser kept the old script, stylesheet, image or page. Such a response now carries noETagwhen its content identity is unknown. Apache, nginx and IIS with the optimizer. Update recommended; no configuration change and no cache purge required. See Upgrade notes. Affected: 1.16.0 to 2.5.2. -
Conditional requests to resources served from the optimizer cache follow HTTP more closely. If a request carries both
If-None-MatchandIf-Modified-Since, only the entity tag is used, as HTTP requires; before, a resource that had changed but kept an older modification date could be answered304 Not Modifiedand the client kept the outdated copy. Entity tags that contain a comma are recognized, so such a resource is revalidated with a304instead of being sent in full, andIf-None-Match: *is answered with304 Not Modified. A stored original that is re-recorded while it is being served now goes out with the headers of the copy actually sent. Apache, nginx and IIS with the optimizer. Update recommended. Affected: 1.16.0 to 2.5.2. -
Optimizer cache entries are now kept apart per site. The optimizer cache key now includes the site’s port. See Upgrade notes. Affected: 1.16.0 to 2.5.2.
-
A failed read of a stored original no longer lets an optimized variant through without the origin’s headers (for example
Access-Control-Allow-OriginorVary: Accept); such a request now goes to the origin, like a cache miss. Apache, nginx and IIS with the optimizer. Affected: 1.16.0 to 2.5.2. -
Resources whose origin states its lifetime only with
Expiresare served with that lifetime, not the optimizer’s type default (300 seconds for CSS and JavaScript, 3600 seconds for images). AnExpiresalready in the past is treated as not freshly cacheable. Apache, nginx and IIS with the optimizer. Affected: 1.16.0 to 2.5.2. -
Lower request latency on Apache and IIS with the optimizer. Requests no longer wait on one another to reach the optimizer cache. While the cache is being opened, for example right after a full cache purge, other requests are answered by the origin instead of waiting. Affected: 1.16.0 to 2.5.2.
-
Apache: caching headers on rewritten HTML and static resources.
Cache-ControlandExpiresset by php-fpm, CGI orHeader always setare now handled like any other origin header: rewritten HTML no longer carries the origin’sCache-Control(with amax-ageors-maxagea shared cache could honour) next to the module’smax-age=0, no-cache, and in-places-maxageon a static resource is merged into a singleCache-Controlheader instead of a second one. mod_php setups never had this problem. Affected: 0.9.13 to 2.5.2. -
Apache with the optimizer: stylesheets and scripts compressed by mod_deflate or mod_brotli are now recorded and optimized. Before, such responses were refused as content-encoded, so browser traffic never fed the optimizer. The compressor still compresses the response on the way out. Affected: 1.16.0 to 2.5.2.
-
Apache: smaller correctness fixes.
- The module’s own 404 responses (unknown
.pagespeed.resources, missing static assets) now use the site’sErrorDocumentinstead of Apache’s built-in error page. Theresource_404_countandslurp_404_countstatistics are still counted. Affected: 0.9.1 to 2.5.2. - A proxy request that fails
ModPagespeedProxyAuthis now rejected with 403. Affected: 1.10.33 to 2.5.2. <Files>and<FilesMatch>sections now apply to.pagespeed.URLs. Affected: 1.1.23 to 2.5.2.- Memory use on long-lived connections no longer grows over time. Affected: 0.10.22 to 2.5.2.
- A deprecated filter enabled in
.htaccesslogs its warning once instead of on every request. Affected: 1.15.0 (from revision r20) to 2.5.2.
- The module’s own 404 responses (unknown
-
IIS: a worker process crash or corrupted response that could occur while rewriting HTML under load is fixed. Affected: 1.15.0 to 2.5.2. Update recommended.
-
IIS: rewritten HTML keeps the origin’s
no-storeandno-transform, andModifyCachingHeaders offis honoured for HTML, as on Apache and nginx. Before, pages marked never-store could land in browser disk and back/forward caches, and HTML that did not go through the classic in-place lookup lostExpiresandLast-ModifieddespiteModifyCachingHeaders off. Affected: 1.15.0 to 2.5.2. -
IIS: the entity tag travels under its standard
ETagname. It was sent asE-Tag, so clients did not get a usable validator, and rewritten HTML kept the origin’sETagfor a body it no longer describes. AHEADrequest for a resource not in the in-place cache is no longer counted and logged as a failed recording. Affected: 1.15.0 to 2.5.2. -
IIS: the module can reach an optimizer worker that runs under another account, for example with the module in an application pool identity and the worker under a service account. Before, every request that needed the optimizer reported
X-Pagespeed-Init-Status: daemon-unavailable. Affected: 1.17.0 to 2.5.2. -
IIS: no worker process failure when a site whose module startup failed is recycled or its configuration is fixed (for example after a missing or unwritable
FileCachePath); such failures counted towards rapid-fail protection. Editingpagespeed.configwhile the site is serving traffic no longer risks a stalled or failed worker process: the previous configuration is retired in the background once its last request has finished. Affected: 1.15.0 to 2.5.2. -
Windows: a full cache purge takes effect while IIS or an ASP.NET Core application is serving. Before, a full purge (
POST /v1/cache/purgewith"scope": "all") could report success without removing anything while the web server had the cache open. The module and theWeAmp.PageSpeedpackage (the ASP.NET Core middleware) now open the cache volume so that a full purge can replace it while open, as on Linux; the web server picks up the empty cache within about a second. If an application with an older module or an olderWeAmp.PageSpeedpackage still holds the volume, the purge reports that the cache volume could not be removed instead of success; the cache keeps serving and its generation is not advanced. A failed full purge also no longer risks stopping the optimizer. Other platforms are unchanged. Affected: 1.17.0 to 2.5.2. -
IIS: requests no longer stall for one second when another module raises a custom notification. Affected: 1.15.0 to 2.5.2.
-
IIS: native memory no longer grows with every response recorded for in-place optimization. Affected: 1.15.0 to 2.5.2.
-
nginx: in-place optimization without the optimizer service no longer slows other clients. Newly seen resources are stored from a background thread, so recording a cache miss no longer adds latency for other clients on the same worker. Under heavy load a recording may be skipped (counted in
ipro_classic_record_dropped); the resource is recorded on a later request. Affected: 1.7.30 to 2.5.2. -
nginx: a remote configuration refresh no longer pauses the worker when the native fetcher is in use. With
RemoteConfigurationUrlandUseNativeFetcher onand the default file cache, requests during a refresh use the local configuration and later requests the refreshed copy. With an external cache (memcached or redis) the module still waits up toRemoteConfigurationTimeoutMsand warns about the combination at startup; with the default fetcher a refresh can still delay requests by up to the timeout. Affected: 1.10.33 to 2.5.2. -
nginx:
nginx -tno longer creates the file cache’s volume files. A configuration test only validates the configuration, so it no longer takes a minute on a slow disk. Normal startup still creates and checks the volumes. Affected: 1.15.0 to 2.5.2. -
nginx: admin and request-path fixes. A request whose scripted option value (
ProcessScriptVariables on) is invalid is served without optimization instead of having its connection closed, and the message-history endpoint answers its refusals with 405 or 429 instead of 200. Affected: 1.9.32 to 2.5.2. -
nginx: reload and shutdown fixes. Reloading with
master_process offno longer crashes (the reload is refused with an error and pagespeed stays off until nginx is restarted), a worker exiting with work outstanding no longer crashes, and the Web Bot Auth key file is rechecked at most every 5 seconds instead of on every signed request. Affected: 1.5.27 to 2.5.2. -
resize_rendered_image_dimensionsuses the largest size of an image that appears more than once on a page, as documented. Before, the first appearance’s size was used, so a larger appearance could get a smaller image that the browser scaled up. Affected: 1.9.32 to 2.5.2.
Action required when upgrading
-
nginx: check nested
location,ifandlimit_exceptblocks. A nested block that sets nopagespeeddirectives now inherits the enclosing location’s settings. If you relied on a nested block escaping them (for example to keep optimization on below a location withpagespeed off), set the directives in the nested block itself. -
CDN or shared cache in front of rewritten HTML: expect fewer HTML hits on caches that key on the full
User-Agent. Rewritten HTML now carriesVary: Accept, Save-Data, User-Agent(with the defaultCoreFilters), or the subset your filters depend on. To keep HTML hit rates high, useImagePreserveURLs onwith the optimizer worker installed so images are selected at their own URLs, or normalize these headers at the cache as described in the deployment guide. Sites whose HTML is not stored by a shared cache, the default, see no change. -
Client reloads and the optimizer cache. A browser reload (
Cache-Control: no-cache,max-age=0orPragma: no-cache) is now answered from the optimizer’s cache. SetDaemonServeHonorRequestFreshness onif you want those requests to go to the origin. -
ETags after the upgrade. Clients may download some optimized resources once more, because their validators change; resources whose origin sends no validator are revalidated with a full response until the optimizer has processed them again. No configuration change and no cache purge are needed.
-
One host name on several ports: purge the optimizer cache once. If you serve one host name on several ports (for example
http://example.com/andhttp://example.com:8080/), purge the optimizer cache once after upgrading, because existing entries may already be mixed between the sites. -
nginx and an optimizer that starts after nginx. No reload is needed any more: each nginx worker process checks again at most once every 30 seconds while requests arrive and turns in-place optimization back on by itself, logging one info line. A split cache volume or other configuration fault still needs a restart.
-
Apache:
ErrorDocument 404now applies to the module’s own 404s. If a site has anErrorDocument 404, requests for unknown.pagespeed.resources and missing static assets now receive that page. -
Windows: a lock file in the cache directory. A small hidden
.pagespeed-module-open.lockfile appears in the optimizer’s cache directory; leave it in place. -
Monitoring
ipro_daemon_served. After the upgrade this statistic counts optimized responses only. Addipro_daemon_served_originalto dashboards or alerts that used it as a health signal; a risingipro_daemon_served_originalwith a flatipro_daemon_servedmeans the optimizer is not producing variants. -
Remove
mobilize,insert_ga,LogMobilizationSamples,AnalyticsIDandUseAnalyticsJsfrom your configuration to silence the new warnings, and thega=component from experiment specs. If you relied oninsert_gafor analytics, add your own analytics snippet. -
Log matching. Module messages now say “optimizer” where they said “daemon”; update log filters or alerts that match the old text.
-
Shared caches and Save-Data. Pages handled by
prioritize_critical_imageswith Save-Data qualities now always carryVary: Save-Data, so a shared cache keeps a copy per Save-Data value. -
Building from source: install Bazel 8.8.1 (or use bazelisk with the repository’s
.bazelversion); scripts that calledscripts/use-envoy-workspace.shor relied onWORKSPACEneed updating. Java is no longer required. If you fetchpagespeed_libraries.conffrom the repository, useinstall/common/pagespeed_libraries.conf.
Deprecations
mobilizeis a no-op. It had no rewriting behaviour of its own. It can still be named and now logs a warning that it has no effect;LogMobilizationSamplesis accepted and ignored with a warning. Enablingmobilizeno longer adds aheadelement to pages without one, and no longer makes the server look up a per-origin property cache page per request.insert_gais a no-op. It injected a Universal Analytics tracker, and Universal Analytics was discontinued in July 2023. It can still be named and now logs a warning;AnalyticsID,UseAnalyticsJsand thega=component of an experiment spec are accepted and ignored with a warning.
pagespeed-optimizer
The optimizer worker, the container images and the WeAmp.PageSpeed NuGet
package.
Added
- Software bill of materials, VEX and signed checksums. Releases of the
host packages include an SPDX 2.3 software bill of materials
(
pagespeed-optimizer-<version>.spdx.json) and an OpenVEX file (pagespeed-optimizer-<version>.vex.json) listing known vulnerabilities in bundled components that do not affect these packages, with the reason for each; both are listed inSHA256SUMS. Each package has a build provenance attestation and an SBOM attestation in the public Sigstore transparency log, andSHA256SUMShas a Sigstore signature (SHA256SUMS.sigstore.json) next to the existing PGP signature. The existinggpgandsha256sumcheck works as before; RELEASING.md lists thegh attestation verifyandcosign verify-blobcommands.
Changed
-
More browsers get WebP and AVIF. When a WebP or AVIF image comes out larger than the optimized image in the original format, the optimizer now tries up to two smaller WebP encodes, or one AVIF encode, at the same visual quality target before falling back to the original format; a browser is not sent a larger image than the original-format one. This applies when an image is optimized afresh, not to an image whose original-format copy is already cached, until that copy expires or is purged.
/v1/statsand the Prometheus metrics reportimage_size_refusedandimage_budget_rescued. -
The worker’s log lines and
--versionoutput, and the nginx module’s load notice, name the product mod_pagespeed. The version number and build commit are unchanged.
Fixed
-
ETags on optimized responses. An optimized script, stylesheet, image or page whose origin sends neither
ETagnorLast-Modifiedcould be answered304 Not Modifiedafter it changed, when the new optimized version had the same size. Optimized responses now carry a validator derived from the source content, and none when no content identity is available, so a stale copy is no longer confirmed as unchanged. Pages, stylesheets and scripts the optimizer leaves unchanged carry anETagagain and answer a matchingIf-None-Matchwith304 Not Modified. With the nginx module, a response revalidated with the origin now carries the sameETagas a cache hit for the same bytes, so the browser gets a304instead of a full response. Update recommended; see Upgrade notes. Affected: 2.0.0 to 2.5.2. -
nginx: a compressed optimized response served right after a 304 revalidation keeps its
Content-Encoding. Before, a gzip or Brotli response markedX-PageSpeed: REVALIDATEDcould be sent without the header, so clients received compressed bytes labelled as plain content. -
Proactive image variants: desktop and tablet browsers get the optimized image again. With the nginx module and
PAGESPEED_PROACTIVE_IMAGE_VARIANTS=trueor--proactive-image-variants, since 2.5.1 desktop browsers could be served the original image in its original format for images up to 768 pixels wide, and tablet browsers that accept only JPEG for images up to 480 pixels wide. An affected image is rebuilt the next time a desktop browser requests it; no purge is needed. Affected: 2.5.1 to 2.5.2, only with proactive image variants enabled (off by default). -
When an origin starts sending
Vary: Acceptfor a URL, the optimized copies stored before the change are dropped at the next origin refresh instead of being served until a purge. Affected: 2.1.0 to 2.5.2. -
The default worker thread count follows the container’s CPU limit. It is now the smallest of the CPUs the worker may run on and the container’s CPU limit (
docker run --cpus, a Kubernetes CPU limit), between 2 and 128; an explicit--num-threadsstill wins. Affected: 2.0.0 to 2.5.2. -
Recovery of a cache volume that failed to open removes the damaged volume files. Before, it removed nothing, and the site ran without optimization on every restart until the file was removed by hand. For a permission, symlink or I/O error, or a volume another running process still holds, nothing is deleted: the reason is logged and the worker starts in degraded mode.
-
Windows: a full cache purge replaces the cache volume while a 2.6.0 web server module or
WeAmp.PageSpeedpackage has it open. See “Windows: a full cache purge takes effect while IIS or an ASP.NET Core application is serving” under mod_pagespeed, Fixed. Affected: 2.0.0 to 2.5.2. -
Windows: the client library and the ASP.NET Core middleware can notify an optimizer worker that runs under another account, for example an IIS application pool identity with the worker under a service account. Before, the connection failed with access denied. Affected: 2.2.0 to 2.5.2.
-
Configuration updates through
PATCH /v1/configno longer pause the worker while the settings are saved to disk. The update still returns once the change is saved; if saving fails, for example because the disk is full, the response carries a warning and the change stays in force until the next restart. Affected: 2.0.0 to 2.5.2. -
A crashed browser renderer during a screenshot or waterfall capture is reported as 502 Bad Gateway (
BAD_GATEWAY) with a message naming the crashed target; 504 is kept for captures that really time out. -
Smaller fixes.
- With gzip (or brotli) compression turned off, the optimizer no longer recompresses and rewrites the stored copy of an image type it cannot optimize after a restart.
- Request headers the nginx module adds for conditional revalidation are handled like every other request header. Affected: 2.0.0 to 2.5.2.
- The
--helptext says--agent-optimize-llms-txtrequires--agent-optimize. - C API:
ps_notify_workerreports an invalid-argument error for a notification it cannot serialize, including a scheme other thanhttporhttps, instead of success; the nginx module does not use this entry point.
Upgrade notes
- ETags change once. Clients may download some optimized resources once more after the upgrade; resources without any validator are revalidated with a full response until the optimizer has processed them again. No purge is needed.
- Worker threads in containers with a CPU limit. The default thread
count may now be lower; set
--num-threadsto keep the previous size. - Windows full purge. The 2.6.0 web server modules and
WeAmp.PageSpeedpackage let a full purge replace the cache volume while the application that uses them has it open. If a full purge reports that the cache volume could not be removed, an application with an older module or an olderWeAmp.PageSpeedpackage holds it: update that application, then purge again.
ASP.NET Core sidecar (WeAmp.PageSpeed.Sidecar, WeAmp.PageSpeed.Sidecar.NativeAssets.Linux)
The sidecar NuGet packages are published with this release.
- The sidecar packages now carry the product version.
- Changed: user-visible strings name the product mod_pagespeed. The NuGet description, the options validator’s error for use off Linux and the build warning for an unsupported runtime identifier say mod_pagespeed instead of “ModPageSpeed 2.0”.
- Fixed: optimized requests keep the client’s scheme behind a TLS
terminator (Inverse mode). An inbound
X-Forwarded-Protois passed through on a plain-HTTP connection and the request’s own scheme is used when it is absent; on HTTPS the real scheme always wins. This ends the redirect loop withUseHttpsRedirection()andhttpabsolute URLs (canonical links, OAuth redirect URIs,Locationheaders) on optimized requests. Affected: 1.15.0 to 1.17.0. - Fixed:
ExcludePathsmeans one thing. Every entry is a path prefix (/api/) or a glob (/admin/*,*.json;*matches any sequence,?any single character), and the middleware and the generated nginx configuration exclude exactly the same paths. Before,*.jsonproduced an invalid nginx configuration,/admin/*also excluded unrelated paths such as/docs/administration, and the documented^/api/never matched in the middleware. Affected: 1.15.0 to 1.17.0. - Fixed: a stuck
nginx -tvalidation is killed and reported with the elapsed time and the output captured so far, instead of a bare cancellation error and a leftover process. New optionPageSpeed:Sidecar:ConfigValidationTimeoutMs(default 60 seconds, was a fixed 15 seconds); non-positive values are rejected at startup. The validation also no longer creates cache volume files, so it finishes faster on a slow disk. Affected: 1.15.0 to 1.17.0. - Fixed: a restart that misses its startup deadline is stopped and retried, and shutdown stops a restarting sidecar. Before, such a restart could leave the sidecar in “restarting” for the life of the app: requests bypassed optimization, health checks reported degraded and shutdown skipped the graceful stop. Each retry counts toward the restart-attempt limit, so a host whose restarts are always slow ends in the failed state instead of a silent bypass. Affected: 1.15.0 to 1.17.0.
- Fixed: housekeeping. Invalid timing options fail at startup, a failed sidecar stops repeating its error, health probes are more reliable, and the per-start socket temp directory is removed on shutdown. Affected: 1.15.0 to 1.17.0.
Sidecar upgrade notes
- Action required: check your
ExcludePathsentries before upgrading. Regular-expression entries such as^/api/, which the option was documented to accept, now fail at startup with a message naming the accepted syntax. Rewrite them as prefixes or globs. A regular expression built only from allowed characters is read as a glob, so/api/.*must become/api/; a startup warning flags entries containing.*or.+. - Check the timing options.
PageSpeed:Sidecar:HealthCheckIntervalMs,HealthCheckTimeoutMsandShutdownTimeoutMsmust be positive and at most ten minutes, or the app fails at startup. - Slow hosts: raise
StartupTimeoutMsif sidecar restarts regularly miss their startup deadline; such restarts now end in the failed state instead of bypassing optimization silently. nginx -tvalidation timeout is configurable throughPageSpeed:Sidecar:ConfigValidationTimeoutMs(default 60 seconds); the new default only changes behaviour on hosts too loaded to finish validation.