Diagnosing Thymeleaf Template Caching Issues in Spring Boot
Diagnose why edited Thymeleaf templates don't update in Spring Boot. Learn to identify caching causes, verify resolver beans, and apply environment-specific fixes.
15 May 2026, 03:05 UTC

Recognizable Condition
You edit and save a Thymeleaf HTML template (e.g., src/main/resources/templates/index.html), refresh the browser, and the rendered page still shows the old markup. The change only appears after a full application restart.
Cause and Diagnostic Table
| Possible Cause | How to Recognize It |
|---|---|
Thymeleaf caching enabled (spring.thymeleaf.cache=true) |
The TemplateEngine reuses parsed templates from memory; file system changes are ignored until the cache is cleared. |
| Missing Spring Boot DevTools | Without DevTools on the classpath, Spring Boot does not automatically disable caching or trigger a restart on file changes. |
Custom TemplateResolver bean override |
A manually defined SpringTemplateResolver bean with setCacheable(true) takes precedence over auto-configuration. |
| Incorrect resource path (Prefix/Suffix) | The application reads templates from a different directory than the one being edited, rendering a stale version from another location. |
Ordered Diagnostic Checks
-
Verify the template location
Confirm the edited file matches the configured template prefix and suffix. Run the following in your project root to locate all HTML templates:
# Unix/macOS find src/main/resources -name "*.html" -type f # Windows PowerShell Get-ChildItem -Path src\main\resources -Recurse -Filter *.html | Select-Object -ExpandProperty FullNameEnsure the file you are editing is the one being served by the application. Required permissions: Read access to source tree. Risk: None.
-
Check the active Thymeleaf cache setting
If Spring Boot Actuator is enabled, query the environment endpoint to see the actual value of the cache property:
curl -s http://localhost:8080/actuator/env | jq '.propertySources[] | select(.name | contains("applicationConfig")) | .properties | .["spring.thymeleaf.cache"]'If the endpoint is unavailable, check
application.propertiesor profile-specific files (e.g.,application-dev.properties). Required permissions: Network access to the actuator port. Risk: Exposing actuator endpoints in production without security. -
Inspect the TemplateResolver bean
Verify if a custom bean is overriding the default behavior. Use the actuator beans endpoint:
curl -s http://localhost:8080/actuator/beans | jq '.[] | select(.bean | contains("templateResolver"))'Check the
cacheableflag and theprefix/suffixproperties. Required permissions: Actuator access. Risk: None. -
Confirm DevTools presence
Check your dependency tree to ensure
spring-boot-devtoolsis present for local development:# Maven mvn dependency:tree | grep -i devtools # Gradle gradle dependencies | grep -i devtoolsIf no output is returned, DevTools is not active. Required permissions: Read access to build files. Risk: None.
Fixes Tied to Findings
-
If caching is enabled unintentionally: Set
spring.thymeleaf.cache=falsein your development profile (e.g.,application-dev.properties). Alternatively, addspring-boot-devtoolsto your dependencies to automate this. -
If a custom TemplateResolver bean forces caching: Modify the bean to disable caching only in non-production profiles to maintain performance in production:
@Bean @Profile("!prod") public SpringTemplateResolver templateResolver() { SpringTemplateResolver resolver = new SpringTemplateResolver(); resolver.setPrefix("classpath:/templates/"); resolver.setSuffix(".html"); resolver.setCacheable(false); // Disable only in non-prod return resolver; } -
If the template path is wrong: Adjust
spring.thymeleaf.prefixandspring.thymeleaf.suffixto point to the correct directory, or move your HTML files to match the existing configuration.
Verification and Limitations
To verify the fix, start the application with spring.thymeleaf.cache=false, change a visible string of text in a template, and refresh the browser. The update should appear without a restart.
Limitations:
- Do not disable caching in production; parsing templates on every request significantly increases CPU usage and response latency.
- Changes to
application.propertiesrequire an application restart to take effect. - Editing templates inside a packaged JAR file will not work; changes must be made to the source directory used by the resolver.
Escalation Criteria
If the internal Thymeleaf cache is disabled but changes still do not appear, investigate the following:
- Artifact Integrity: Verify the deployed JAR actually contains the update:
jar -tf target/myapp.jar | grep templates/index.html. - External Caching: Check for browser cache (perform a hard refresh via
Ctrl+Shift+R), reverse-proxy caching (NGINX/Apache), or CDN layers. - Resolver Priority: If multiple
TemplateResolverbeans exist, ensure the intended one is marked@Primaryor has the correct@Order.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.