# Declarations that are rejected, and how late you find out 1. key and keyGenerator together startup : FAILED - java.lang.IllegalStateException Invalid cache annotation configuration on 'public java.lang.String com.ankurm.caching.InvalidDeclarationsTest$BothKeyAndGenerator$Svc.call(java.lang.String)'. Both 'key' and 'keyGenerator' attributes have been set. These attributes are mutually exclusive: either set the SpEL expression used tocompute the key at runtime or set the name of the KeyGenerator bean to use. --- 2. sync = true with unless --- startup : clean first call: java.lang.IllegalStateException A sync=true operation does not support the unless attribute on 'Builder[public java.lang.String com.ankurm.caching.InvalidDeclarationsTest$SyncWithUnless$Svc.call(java.lang.String)] caches=[c] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='#result != null' | sync='true'' --- 3. sync = true across two caches --- startup : clean first call: java.lang.IllegalStateException A sync=true operation is restricted to a single cache on 'Builder[public java.lang.String com.ankurm.caching.InvalidDeclarationsTest$SyncTwoCaches$Svc.call(java.lang.String)] caches=[c1, c2] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='true'' --- 4. @Cacheable and @CacheEvict on one method --- startup : clean first call: java.lang.IllegalStateException A sync=true operation cannot be combined with other cache operations on 'public java.lang.String com.ankurm.caching.InvalidDeclarationsTest$CacheableAndEvict$Svc.call(java.lang.String)' --- 5. a cache name that spring.cache.cache-names does not declare --- startup : clean first call: java.lang.IllegalArgumentException Cannot find cache named 'unknown' for Builder[public java.lang.String com.ankurm.caching.InvalidDeclarationsTest$UndeclaredCache$Svc.call(java.lang.String)] caches=[unknown] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false' Only the first of these is a compile-time-shaped mistake. The rest start a perfectly healthy application and throw on a code path that may not be hit for hours.